代码之家  ›  专栏  ›  技术社区  ›  Demaunt

Python模拟到C++指针到类成员

  •  0
  • Demaunt  · 技术社区  · 5 年前

    是否可以创建指向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 回复  |  直到 5 年前
        1
  •  2
  •   bruno desthuilliers    5 年前

    Python在内存模型和“变量”真的完全不同于C++,所以你的问题没有意义。 I strongly suggest you read this 为了理解为什么“指针”的概念不适用于Python。

    wrt/your 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 功能(是,“功能”-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 类对象,但属于 实例,所以这里您得到一个属性错误。

    现在,即使您尝试Quamrana的代码片段(使用 实例),您将通过attributeError问题,但代码仍然不起作用,即:

    def boo(pointer_to_member):
        pointer_to_member = 321
    
    instance = PClass()
    boo(instance.a)
    

    不会引发错误,但仍不会更新 instance.a . 这里的原因是我链接到的整篇文章的主题,所以我不想太详细,但要想长话短说,python变量只是一个名称,它不是内存地址,所以在上面的代码中, 实例。 是第一次评估,并且值 int 实例绑定到 实例。 )传递给 boo() 在“指向成员的指针”下。此名称是本地名称,因此重新绑定它只影响函数的本地命名空间,此时代码完全不知道 instance 也不是 属性。

    现在,如果你想解释一下你想解决的问题,我们当然可以给你指出正确的蟒蛇解决方案。重点是:在Python中尝试编写C++与试图在C++中编写Python不同语言、不同的习语和模式一样无用。

    所以类有方法,但没有成员?当类的实例同时具有这两个属性时?

    在Python中,我们称为“属性”,而不是“成员”。是的,类也可以有属性(类是对象,类的实例 type 类),但它们在类的所有实例之间共享。fwiw,“方法”实际上是类属性(是的,函数也是对象——实际上,所有东西都是对象——它们不存在于不同的名称空间中)。

    此外,实例本身不具有“方法”——这些方法是类对象的属性(实际上也是C++中的情况),但是Python的属性查找规则(在“点”访问中调用的代码)在类本身(以及它的父类)中查找名称,如果在实例本身上找不到的话。您可以阅读我链接到的第二篇文章,了解更多关于python“methods”真正是什么(本文需要一个更新来反映python3的更改,但是除了 Class.methodname 收益率)。

        2
  •  1
  •   quamrana    5 年前

    你好像在搅拌 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 成员。但是,每个实例 有一个 成员,因为初始化程序创建了一个。

    更新

    但是正如@bruno指出的,函数 boo 上面没有做什么,所以也许你想要一些不同的东西:

    def zoo(inst, member_name):
        setattr(inst, member_name, 322)
    
    # call like this:
    zoo(instance, "a")
    

    这仍然不是 pointer-to-member 正如C++一样,但是它可能是你所要寻找的。