如何使用getattr调用方法? 我想创建一个元类,它可以调用以“oposite_”开头的其他类的非现有方法。该方法应具有相同数量的参数,但返回相反的结果。
def oposite(func):
return lambda s, *args, **kw: not oposite(s, *args, **kw)
class Negate(type):
def __getattr__(self, name):
if name.startswith('oposite_'):
return oposite(self.__getattr__(name[8:]))
def __init__(self,*args,**kwargs):
self.__getattr__ = Negate.__getattr__
class P(metaclass=Negate):
def yep(self):
return True
def maybe(self, sth):
return sth
但问题在于
self.__getattr__(sth)
返回一个NoneType对象。
>>> p = P()
>>> p.oposite_yep() #should be False
Traceback (most recent call last):
File "<pyshell#115>", line 1, in <module>
p.oposite_yep()
TypeError: <lambda>() takes at least 1 positional argument (0 given)
>>> p.oposite_maybe(False) #should be true
如何处理?
答案 0 :(得分:0)
您忘记处理属性名称不以'oposite_'
开头的情况。
答案 1 :(得分:0)
class Negate(type):
def __getattr__(self, name):
if name.startswith('oposite_'):
def oposite(*args,**kwargs):
return not getattr(self,name[8:])(*args,**kwargs)
return oposite
else:
raise AttributeError("%r object has no attribute %r" %
(type(self).__name__, name))
def __init__(self,*args,**kwargs):
self.__getattr__ = Negate.__getattr__
class P(metaclass=Negate):
def yep(self):
return True
def same(self,x,y):
return x==y
p=P()
print(p.oposite_yep())
# False
print(p.oposite_same(1,2))
# True
print(p.nope())
顺便说一句,您也可以使用类装饰器而不是元类来执行此操作:
def Negater(cls):
def __getattr__(self, name):
if name.startswith('oposite_'):
def oposite(*args,**kwargs):
return not getattr(self,name[8:])(*args,**kwargs)
return oposite
else:
raise AttributeError("%r object has no attribute %r" %
(type(self).__name__, name))
setattr(cls,'__getattr__',__getattr__)
return cls
@Negater
class P():
....
答案 2 :(得分:0)
错误为"TypeError: <lambda>() takes at least 1 positional argument (0 given)
"
这与你的元类魔法没有任何关系,因为你没有将任何参数传递给lambda
函数。
执行此操作时:
p.oposite_yep
它会调用__getattr__
,它会返回opposite()
的结果,这是一个lambda
函数。
返回你的lamda函数,它是动态创建的,并且永远不会出现在实例中。它不会作为第一个参数接收'self':它只是一个动态返回的匿名函数。
所以当你这样做时:
p.oposite_yep()
你基本上调用lambda,没有任何参数,导致错误。