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.但我认为我需要在课堂上这样做,因为我需要存储一些额外的信息(比如元数据)(这是我真实问题的简化版).它是否可能以及如何,如果是这样的话?很抱歉没有在一开始就指定这个.
使用函数包装器而不是第一类.关闭将照顾其余的:
>>> 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)