Python模拟C++指向类成员的指针
Python analog to C++ pointer to class member
是否可以创建指向Python类成员(而不是方法)的指针?
我想要这样的东西:
class PClass:
def __init__(self):
self.a = 123
def foo(self, a):
self.a = a
# this works
def bar(pointer_to_method):
py_ex = PClass()
pointer_to_method(py_ex, 321)
bar(PClass.foo)
# this does not
def boo(pointer_to_member):
py_ex = PClass()
py_ex.pointer_to_member = 321
boo(PClass.a)
在C++中,我可以创建指针类成员和类函数
class CClass
{
public:
int CClass_property_1;
int CClass_property_2;
void CClass_method(const int& param){}
};
auto method_pointer = &CClass::CClass_method;
auto propery_1_pointer = &CClass::CClass_property_1;
propery_1_pointer = &CClass::CClass_property_2;
现在我可以使用CClass的实例从指针调用函数,或者访问属性。
我对Python模拟C++指针到类属性(而不是方法)感兴趣
Python在内存模型和"变量"到底是什么方面与C++完全不同,所以你的问题实际上没有意义。我强烈建议您阅读本文,以理解为什么"指针"这一概念在Python中不适用。
wrt/您的python片段:
class PClass:
def __init__(self):
self.a = 123
def foo(self, a):
self.a = a
# this works
def bar(pointer_to_method):
py_ex = PClass()
pointer_to_method(py_ex, 321)
bar(PClass.foo)
这是因为PClass.foo
求值给未绑定的方法(python2.x)或直接求值给foo
函数(是的,"function"/cfhttps://wiki.python.org/moin/FromFunctionToMethod)-但在这两种情况下,都指向一个可调用对象,该对象要么是您的函数,要么是它周围的小包装器。
# this does not
def boo(pointer_to_member):
py_ex = PClass()
py_ex.pointer_to_member = 321
boo(PClass.a)
这不能正常工作,因为a
不是PClass
类对象的属性,而是PClass
实例的属性,所以这里会得到AttributeError。
现在,即使您尝试quamrana的代码片段(使用PClass
实例),您也会通过AttributeError问题,但代码仍然无法工作,即:
def boo(pointer_to_member):
pointer_to_member = 321
instance = PClass()
boo(instance.a)
不会引发错误,但仍不会更新instance.a
。这里的原因是我链接到的整篇文章的主题,所以我不想太多细节,但长话短说,python变量只是一个名称,而不是内存地址,所以在上面的代码中,instance.a
是第一个求值的,值(绑定到instance.a
的int
实例)以"pointer_to_member"的名称传递给boo()
。这个名称是一个本地名称,因此重新绑定它只会影响函数的本地命名空间,此时代码对instance
和a
属性一无所知。
现在,如果你想解释一下你试图在这里解决的问题,我们当然可以为你指出合适的蟒蛇解决方案。重点是:尝试用Python编写C++和尝试用C++编写Python一样无用——不同的语言、不同的习惯用法和模式。
所以类有方法,但没有成员?而类的实例两者都有?
在Python中,我们说的是"属性",而不是"成员"。是的,类也可以有属性(类是对象,type
类的实例),但这些属性在类的所有实例之间共享。FWIW,"方法"实际上是类属性(是的,函数也是对象——实际上所有东西都是对象——它们不存在于不同的命名空间中)。
此外,实例本身并没有"有"方法——这些方法是类对象的属性(实际上C++FWIW中也是如此)——但Python的属性查找规则(在"点"访问中调用的代码)会在实例本身上找不到类(及其父类)中的名称。您可以阅读我链接的第二篇文章,了解更多关于Python"方法"的内容(这篇文章需要更新以反映Python3的更改,但除了Class.methodname
产生的内容外,它仍然基本准确)。
您似乎在混合classes
和instances
。Python中的区别比C++中的更清楚。
以下是您的代码重写:
class PClass:
def __init__(self):
self.a = 123
def foo(self, a):
self.a = a
def bar(pointer_to_method):
pointer_to_method(321)
def boo(pointer_to_member):
pointer_to_member = 321
instance = PClass()
bar(instance.foo) # Note that I pass foo bound to instance in the one parameter
boo(instance.a) # Again the member a is bound to instance in the one parameter
PClass
从未有过a
成员。但是,PClass
的每个实例都有一个a
成员,因为初始化程序创建了一个。
更新
但正如@Bruno所指出的,上面的函数boo
没有任何作用,所以也许你想要一些不同的东西:
def zoo(inst, member_name):
setattr(inst, member_name, 322)
# call like this:
zoo(instance, "a")
这仍然不是C++所拥有的pointer-to-member
,但它可能正是您想要的。
- 从成员指针到整个结构/类的强制转换
- OOP 中的单成员指针
- 使用结构成员指针在C++中填充结构
- 聚合初始化,将成员指针设置为同一结构成员
- 空指针常量 (nullptr)、空指针值和空成员指针值之间有什么区别?
- 共享 C++ 的数据成员指针
- 如何声明指向成员内容的成员指针m_pmd/m_pmf并访问它们?
- 从类C++外部调用指向成员方法的成员指针
- 结构成员指针是否自动初始化为零?
- 如何删除类内类类型的类成员指针
- 是否打印指向已定义 int 的成员指针
- 指向常量的成员指针
- 通过此指针访问时的成员差异和自身的成员指针(简单的 QT 示例问题)
- 类数据成员指针的非类型模板参数包无法使用 gcc 编译
- 为什么我不能在同一行中定义两个相同类型的类的成员指针
- 将类成员指针传递给 Lambda 捕获列表 c++11
- 在单一实例类中将成员指针设置为 null 的正确方法是什么
- 无法删除在destructor中的成员指针的课程
- 删除对象而不调用成员指针的析构函数
- 当派生类的基类具有成员指针时,对其进行深层复制