Python类似C ++的指向类成员的指针

时间:2019-02-11 15:17:57

标签: python c++

是否可以创建指向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 ++的指向类属性(不是方法)的指针感兴趣

2 个答案:

答案 0 :(得分:2)

Python在内存模型和“变量”的真正含义上与C ++完全不同,因此您的问题没有任何意义。 I strongly suggest you read this了解为什么“指针”这一单纯的概念在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”-cf https://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,然后将值(绑定到int的{​​{1}}实例)以名称“ pointer_to_member”传递给instance.a。此名称是本地名称,因此重新绑定它只会影响函数的本地名称空间,此时,代码完全不知道boo()instance属性。

现在,如果您愿意在这里解释您要解决的问题,我们当然可以为您提供正确的pythonic解决方案。关键是:尝试用Python编写C ++和尝试用C ++编写Python一样没有用-不同的语言,不同的习语和模式。

  

所以Class有方法,但没有成员?而类的实例同时具有吗?

在Python中,我们说的是“属性”,而不是“成员”。是的,类也可以具有属性(类是ARE对象,是a类的实例),但是它们在该类的所有实例之间共享。 FWIW,“方法”实际上是类属性(是的,函数也是对象-实际上,所有内容都是对象,并且它们不存在于不同的名称空间中)。

此外,实例本身并不“拥有”方法-方法是类对象的属性(在C ++ FWIW中实际上也是这种情况)-但是Python的属性查找规则(在“点划线”上调用的代码如果在实例本身上找不到名称,则在类(及其父母)中查找名称。您可以阅读我链接的第二篇文章,以进一步了解Python的真正方法(该文章可能需要进行更新以反映Python3的更改,但除type产生的内容外,大部分内容还是准确的)。

答案 1 :(得分:0)

似乎您正在混用<a href="#"> <i class="fa fa-gears fa-fw"></i> {{ myFunction() }} <span class="fa arrow"></span> </a> classes。与C ++相比,Python的区别更加明显。

这是您的代码的重写:

instances

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成员,因为初始化程序会创建一个成员。

更新

但是正如@Bruno所指出的那样,上面的函数a并没有任何作用,所以也许您想要一些不同的东西:

boo

这仍然不是C ++的def zoo(inst, member_name): setattr(inst, member_name, 322) # call like this: zoo(instance, "a") ,但它可能正是您想要的。