自我参数和元编程

Kir*_*rov 2 python metaprogramming

嗯,代码说的更多(我已经对一些东西进行了硬编码,以隔离问题并缩短问题):

class wrapper:
    def __init__( self, func ):
        self.func = func
    def __call__( self, *args ):
        print( "okay, arg = ", args[0] )
        self.func( self, args )

class M( type ):
    def __new__( klass, name, bases, _dict ):
        _dict[ "f" ] = wrapper( _dict[ "f" ] ) 
        return type.__new__( klass, name, bases, _dict )

class AM( metaclass = M ):
    def __init__( self ):
        self.a = 0 
    def f( self, a ):
        self.a = a 

am = AM()
print( am.a ) # prints 0, expected
am.f( 1 )  # prints: "okay, arg = 1"
print( am.a ) # prints 0 again, also expected
Run Code Online (Sandbox Code Playgroud)

我想要显示第二个印刷品1,而不是0.换句话说,将"真实的自我"传递给我的包装器是否可能,如果是这样 - 如何?

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

有任何想法吗?


编辑 - 感谢所有的答案,来自我的+1.但我认为我需要在课堂上这样做,因为我需要存储一些额外的信息(比如元数据)(这是我真实问题的简化版).它是否可能以及如何,如果是这样的话?很抱歉没有在一开始就指定这个.

San*_*nta 6

使用函数包装器而不是第一类.关闭将照顾其余的:

>>> 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
>>>
Run Code Online (Sandbox Code Playgroud)