在 Python 中使用 getattr 调用方法
如何使用 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
这该如何处理呢?
How to call a method using getattr?
I want to create a metaclass, which can call non-existing methods of some other class that start with the word 'oposite_'. The method should have the same number of arguments, but to return the opposite result.
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
But the problem is that
self.__getattr__(sth)
returns a NoneType object.
>>> 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
How to deal with this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
顺便说一句,您也可以使用类装饰器而不是元类来完成此操作:
By the way, you can also do this with a class decorator instead of a metaclass:
您忘记处理属性名称不以
'oposite_'
开头的情况。You forgot to handle the case where the attribute name doesn't start with
'oposite_'
.错误是
“TypeError:() 至少需要 1 个位置参数(给定 0 个)
“
这与你的元类魔法无关,这是因为你没有将任何参数传递给
lambda
函数。当你这样做时:
它调用
__getattr__
,它返回opposite()
的结果,这是一个lambda
函数。返回您的 lamda 函数,它是动态创建的,并且永远不会绑定到实例。它不会接收“self”作为第一个参数:它只是一个动态返回的匿名函数,
所以当你这样做时:
你基本上是在不带任何参数的情况下调用 lambda,这会导致错误。
The error is
"TypeError: <lambda>() takes at least 1 positional argument (0 given)
"
This has nothing to do with you metaclass magic, it's because you don't pass any argument to the
lambda
function.When you do this:
It call
__getattr__
, which returns the result ofopposite()
, which is alambda
function.Your lamda function is returned, it is created on the fly, and never bouned to the instance. It won't receive 'self' as a first argument: it's just an anonymous function returned on the fly.
So when you do this:
You basically call the lambda, without any argument, which cause the error.