如何在方法中访问qux
?我真的必须在foo()
的正文中再次定义它,还是有办法从self
导入它?
class Baz(object):
qux = lambda x : x + '_quux'
def foo(self, bar=qux('fred')):
print bar
print qux('waldo')
# NameError: global name 'qux' is not defined
print Baz.qux('waldo')
# TypeError: unbound method <lambda>() must be called with Baz instance as first argument (got str instance instead)
print Baz.qux(self, 'waldo')
# TypeError: <lambda>() takes exactly 1 argument (2 given)
print self.qux('waldo')
# TypeError: <lambda>() takes exactly 1 argument (2 given)
答案 0 :(得分:7)
如果您希望能够在课堂上访问某个方法,则必须使用classmethod
或staticmethod
。
class Baz(object):
qux = staticmethod(lambda x : x + '_quux')
答案 1 :(得分:1)
一种解决方案是使用
qux = staticmethod(lambda x : x + '_quux')
并以
的形式访问它Baz.qux('waldo')
我只是将它移出课堂。
答案 2 :(得分:1)
qux
被视为一个实例方法,因为这是类似函数的类成员的默认处理(更具体地说,Baz.qux
有__get__
隐式调用“将“第一个参数绑定到实例,当您通过实例查找时”。但是,您尚未在开头提供self
参数。因此,baz
会绑定到x
lambda参数。
Python中的'self'这个名字并不神奇;它只是惯例。方法绑定总是通过绑定到函数的第一个参数来工作。
如果你聪明的话,你可以自己看看:
class Baz(object):
qux = lambda x: x + '_quux'
def foo(self): return self.qux()
Baz().foo() # TypeError: unsupported operand type(s) for +: 'Baz' and 'str'
# because after binding Baz() to 'x', we get Baz() + '_quux'
一种解决方案是明确地将qux
设为staticmethod
,就像在Sven Marnach的回答中一样。 (你也可以把它变成classmethod
,这是一个特定于Python的概念,它更强大; staticmethod
更接近于像Java这样的语言中static
关键字的行为。)注意与在Java中一样,您也可以在staticmethod
内访问self.qux
foo
。这可以通过用__get__
安装的新机器替换普通的staticmethod
机器来实现功能。
另一种解决方案是在lambda参数中提供self
参数。如果你实际上不想要“静态”行为(即需要用self
实际做某事),这很有用 - 但它看起来就像你做的那样。为了完整起见,这看起来像:
qux = lambda self, x: x + '_quux'
def foo(self):
return self.qux('foo')