以下是从学习Python中提取和改编的代码,第5行lambda
中return lambda *args: '[Getattr str]'
的用法是什么,似乎print(X.__str__())
期望0个参数,是*args
不必要吗?
class GetAttr:
def __getattr__(self, attr):
print('getattr: ' + attr)
if attr == '__str__':
return lambda *args: '[Getattr str]'
else:
return lambda *args: None
X = GetAttr()
print(X.__call__('why', 'any', 'number', 'of', 'arguments', 'here'))
print(X.__str__()) # but not here?
答案 0 :(得分:2)
当attr == '__str__'
时,函数需要返回一个可调用对象,因为__str__
应该是一个方法。简单地返回一个字符串会给你一个错误,抱怨说' str'对象不可调用。
但是,不需要*args
,因为永远不会使用任何参数调用__str__
。这就足够了:
return lambda: '[Getattr str]'
请注意,如果您使用python2并按照建议继承object
,则示例不起作用。如果你使用python3,它也不起作用。这是这些情况下的输出:
getattr: __call__ None <__main__.GetAttr object at 0xb728ff6c>
为什么__getattr__
时无法调用attr == '__str__'
?
这是因为基类object
已经实现了默认的__str__
方法,而我们的__getattr__
函数仅用于缺少属性。要修复示例,我们必须使用__getattribute__
方法,而不是beware of the dangers。
class GetAttr(object):
def __getattribute__(self, attr):
print('getattr: ' + attr)
if attr == '__str__':
return lambda: '[Getattr str]'
else:
return lambda *args: None
更好,更易读的解决方案是简单地覆盖__str__
方法。
class GetAttr(object):
def __getattr__(self, attr):
print('getattr: ' + attr)
return lambda *args: None
def __str__(self):
return '[Getattr str]'
但是虽然它是更好的python,但这个例子的大部分内容都已丢失。
答案 1 :(得分:0)
它用于粉碎任何交给它的args。无论你放入__str__()
多少个args,它总会忽略它们。
另一方面,这是非常糟糕的Python。你可能想尝试别的东西
答案 2 :(得分:0)
lambda
使函数返回一个函数。
答案 3 :(得分:0)
是的,在这种情况下没有必要,因为X.__str__()
将始终在没有参数的情况下被调用。它取决于使用args错误调用时所需的行为:
str1 = lambda *args: "[Getattr str]"
str2 = lambda : "[Getattr str]"
str1(1,2,3) #works, args ignored
str2(1,2,3) #throws runtime error