2011-06-09 93 views
4

如何访问qux里面的方法?我是否真的必须在foo()的主体内再次定义它,或者有没有办法从self导入它?python函数的默认参数

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)     

回答

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,如斯文Marnach的答案。 (您也可以将其设置为classmethod,这是一个更为强大的Python特定概念; staticmethod与Java中的static关键字的行为更加接近)注意,与Java一样,您还可以访问staticmethod作为self.quxfoo之内。这可以通过用staticmethod替换正常的__get__机器用于安装新机器的功能来实现。

另一种解决方案是在lambda参数中提供self参数。如果你实际上不想要“静态”行为(即,实际上需要用self做某件事),这很有用 - 但它看起来非常像你一样。只是为了完整性,这将是这样的:

qux = lambda self, x: x + '_quux' 
def foo(self): 
    return self.qux('foo') 
1

一种解决方案是使用

qux = staticmethod(lambda x : x + '_quux') 

和访问它作为

Baz.qux('waldo') 

我只是将它移出类的。

+0

谢谢你,我的实际使用情况是从os.path中进口ABSPATH,目录名,加盟,真实路径,expanduser像 ',''PSD =拉姆达S:真实路径(join(dirname(abspath(__ file__)),s))''但我不想用全部的垃圾来污染全局命名空间。 – wim 2011-06-09 02:48:42

+0

@wim,你的代码污染了更糟糕的类名称空间。只需在模块级别 – 2011-06-09 02:52:36

+0

进口它哦,这对waldo有效,但是为fred破坏了..现在我得到了'TypeError:'staticmethod'对象在第5行不可调用' – wim 2011-06-09 02:57:35

7

如果您希望能够访问某个方法,那么您必须使用classmethodstaticmethod

class Baz(object): 
    qux = staticmethod(lambda x : x + '_quux') 

don't do that

+1

对于有趣的博客链接, – Gerrat 2011-06-09 02:37:52

+1

哈哈是啊我的upvote是链接,而不是解决方案。 – Jordan 2011-06-09 02:47:18

+0

“如果你没有为互操作性原因实现现有的XML标准,创建某种导入/导出格式,或者创建某种XML编辑器或处理工具,那么就不要这样做。甚至不要将其用于新的导入/导出格式; JSON在Python中使用起来更容易。 – 2011-06-09 02:51:03