Python 自参数和元编程

Python 自参数和元编程,python,metaprogramming,Python,Metaprogramming,好的,代码更能说明问题(我对一些事情进行了硬编码,以隔离问题并缩短问题): 我希望第二次打印显示1,而不是0。换句话说,是否有可能,如果有,如何将“真实的自我”传递给我的包装 注意:我知道为什么会打印0,我知道这里的问题是什么(包装器的self被传递,而不是调用f的对象),但我不知道如何解决它 有什么想法吗 编辑-谢谢大家的回答,+1来自我。但我认为我需要用类来实现这一点,因为我需要存储一些额外的信息(比如元数据)(这是我真正问题的简化版本)。可能吗?如果可能,如何实现?很抱歉,没有在一开始就

好的,代码更能说明问题(我对一些事情进行了硬编码,以隔离问题并缩短问题):

我希望第二次打印显示
1
,而不是
0
。换句话说,是否有可能,如果有,如何将“真实的自我”传递给我的包装

注意:我知道为什么会打印
0
,我知道这里的问题是什么(
包装器的self被传递,而不是调用
f
的对象),但我不知道如何解决它

有什么想法吗



编辑-谢谢大家的回答,+1来自我。但我认为我需要用类来实现这一点,因为我需要存储一些额外的信息(比如元数据)(这是我真正问题的简化版本)。可能吗?如果可能,如何实现?很抱歉,没有在一开始就指定它。

制作
包装器
a,以便您知道要插入的特定实例。

使用函数包装器,而不是类1。关闭将解决其余问题:

>>> def wrapper(meth):
...     def _wrapped_meth(self, *args):
...             print('okay, arg = ', args)
...             meth(self, *args)
...     return _wrapped_meth
...
>>> class M(type):
...     def __new__(klass, name, bases, dct):
...             dct['f'] = wrapper(dct['f'])
...             return type.__new__(klass, name, bases, dct)
...
>>> class AM(metaclass=M):
...     def __init__(self):
...             self.a = 0
...     def f(self, a):
...             self.a = a
...
>>> am = AM()
>>> print(am.a)
0
>>> am.f(1)
okay, arg = (1,)
>>> print(am.a)
1
>>>

您可以将您的
包装器
类设置为非数据描述符,如Raymond Hettinger的《优秀》一节所述——在本例中,这非常简单,因为它只意味着提供类a
\uuuu get\uuu()
方法,该方法创建并返回所需的包装方法

我的意思是:

class wrapper:
    def __init__( self, func ):
        self.func = func

    def __get__( self, instance, owner ):
        def wrapped( *args ):
            print( "okay, arg = ", args[0] )
            return self.func( instance, *args )
        return wrapped

使用类意味着您可以根据需要轻松添加其他成员和/或元数据。

闭包不是唯一的成分。您只会得到
self
,因为类将
wrapper
识别为一个方法,并为其生成一个实例方法描述符。很好+1.现在。你能解释一下这是怎么回事吗。我的意思是-包装器..我见过这样的包装器,但它们都返回帮助函数,在本例中-
\u wrapped\u meth
。在这里,函数返回其参数-
meth
。何时以及如何调用/使用
\u包装的\u meth
。@delnan-真的吗?我可以在课堂上做这个吗?怎么用?因为我需要在包装器中存储一些附加信息—一些其他成员(元数据)等。@Kiril:当然可以,如果您不介意进入描述符—请参阅其他答案。但是请注意,闭包也可以有额外的状态(只需将局部变量添加到
wrapper
中,并在
\u wrapped\u meth
中使用它们),这只在需要其他方法时才变得不切实际。@Kiril Kirov-Oops,
return meth
应该是
return\u wrapped\u meth
,你能给我一些例子吗?我没有得到它,我丢失了一些东西…(在C++中没有类似的东西,对吗?)描述符只是一个类,它在调用描述符的代码< <代码> > yGETSug()> <代码>或<代码>我想这对我会有用的。但是接下来,如何使用参数调用函数
\uuu get\uu
接受3个参数-
self、obj、objtype
。在
\uuuu init\uuuu
中,我可以将函数存储为成员,但是参数呢?另外,在
\uuu get\uuu
中,我无法返回
self.func(obj)
?(
self.func
是存储的cunstion,
obj
是调用对象;当我返回
self.func
时,这确实返回函数,但是如果返回
self.func(obj)
:?我需要这个,看起来,第一个参数(self)应该显式传递吗?否则,我会因为参数较少而出错)非常感谢!返回适当设置类属性的函数。在看到您的答案之前,我编辑了我的注释。不管怎样,我明白你的意思,我会努力的。+1-这正是我所做的,结合了其他两个答案(=
class wrapper:
    def __init__( self, func ):
        self.func = func

    def __get__( self, instance, owner ):
        def wrapped( *args ):
            print( "okay, arg = ", args[0] )
            return self.func( instance, *args )
        return wrapped