C++成员Python等价

2024-10-01 17:28:21 发布

您现在位置:Python中文网/ 问答频道 /正文

在Python中,C++成员指针的等价物是什么?基本上,我希望能够在Python中复制类似的行为:

// Pointer to a member of MyClass
int (MyClass::*ptMember)(int) = &MyClass::member; 

// Call member on some instance, e.g. inside a function to 
// which the member pointer was passed 
instance.*ptMember(3)

接下来的问题是,如果成员是属性而不是方法怎么办?是否可以在不指定实例的情况下存储/传递指向属性的“指针”?在

一种方法显然是传递一个字符串并使用eval。但是有没有更干净的方法呢?在

编辑:现在有几个非常好的答案,每个答案都根据上下文提供有用的信息。我最后使用了我的答案中描述的内容,但是我认为其他的答案对于任何人来说都是非常有帮助的。所以,我现在不接受任何一个。在


Tags: ofto方法instance答案属性onmyclass
3条回答

假设一个Python类:

class MyClass:
    def __init__(self):
        self.x = 42

    def fn(self):
        return self.x

与C++函数指针的等价关系,则是:

^{pr2}$

你可以从一个类(上面的MyClass.fn)中获取一个方法,它就变成了一个普通函数!函数和方法之间的唯一区别是第一个参数通常被称为self!所以你可以用C++中的实例调用:

o = MyClass()
print(fn(o)) # prints 42
<>但是,更有趣的是,你也可以接受绑定成员函数的“地址”,它在C++中不起作用:

o = MyClass()
bfn = o.fn
print(bfn()) # prints 42, too

关于对物业的跟进,这里已经有很多解决这个问题的答案,只要它仍然是一个问题。在

我对字符串方法不满意,所以做了一些测试。这似乎很有效,避免了传递字符串:

import types

# Our test class
class Class:

    def __init__(self, val):
        self._val = val

    def method(self):
        return self._val

    @property
    def prop(self):
        return self._val

# Get the member pointer equivalents
m = Class.method
p = Class.prop

# Create an instance
c1 = Class(1)

# Bind the method and property getter to the instance
m1 = types.MethodType(m, c1)
p1 = types.MethodType(p.fget, c1)

# Use
m1()  # Returns 1
p1()  # Returns 1

# Alternatively, the instance can be passed to the function as self
m(c1)  # Returns 1
p.fget(c1)  # Returns 1

最适合的可能是^{}

from operator import attrgetter
foo_member = attrgetter('foo')
bar_member = attrgetter('bar')
baz_member = attrgetter('baz')

class Example(object):
    def __init__(self):
        self.foo = 1

    @property
    def bar(self):
        return 2

    def baz(self):
        return 3

example_object = Example()
print foo_member(example_object) # prints 1
print bar_member(example_object) # prints 2
print baz_member(example_object)() # prints 3

attrgetter所采用的机制与普通的点式访问完全相同,因此它适用于任何使用点访问的对象。实例字段、方法、模块成员、动态计算的属性等等。对象的类型也不重要;例如,attrgetter('count')可以检索列表、元组、字符串的count属性,或者其他任何具有count属性的对象。在


对于某些类型的属性,可能有更具体的成员指针之类的东西。例如,对于实例方法,可以检索未绑定方法:

^{pr2}$

这要么是实现该方法的特定函数,要么是围绕该函数的非常薄的包装器,具体取决于Python版本。它是类型特定的;list.count不适用于元组,tuple.count不适用于列表。在

对于属性,可以检索属性对象的fgetfset和{},这些函数实现获取、检索和删除属性管理的属性:

example_bar_member = Example.bar.fget
print example_bar_member(example_object) # prints 2

我们没有为这个属性实现setter或deleter,因此fset和{}是{}。这些也是特定于类型的;例如,如果example_bar_member处理正确的列表,example_bar_member([])将引发一个AttributeError,而不是返回{},因为列表没有bar属性。在

相关问题 更多 >

    热门问题