没有多少人知道这个功能,但Python的功能(和方法)可以有属性.看吧:
>>> def foo(x): ... pass ... >>> foo.score = 10 >>> dir(foo) ['__call__', '__class__', '__delattr__', '__dict__', '__doc__', '__get__', '__getattribute__', '__hash__', '__init__', '__module__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', 'func_closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name', 'score'] >>> foo.score 10 >>> foo.score += 1 >>> foo.score 11
Python中此功能的可能用途和滥用情况是什么?我知道的一个好用途是PLY使用docstring将语法规则与方法相关联.但是自定义属性呢?有充分的理由使用它们吗?
我通常使用函数属性作为注释的存储.假设我想以C#的方式编写(表明某个方法应该是Web服务接口的一部分)
class Foo(WebService): @webmethod def bar(self, arg1, arg2): ...
然后我可以定义
def webmethod(func): func.is_webmethod = True return func
然后,当webservice调用到达时,我查找方法,检查底层函数是否具有is_webmethod属性(实际值是不相关的),如果方法不存在或者不打算通过Web调用,则拒绝服务.
我已经将它们用作函数的静态变量.例如,给出以下C代码:
int fn(int i) { static f = 1; f += i; return f; }
我可以在Python中类似地实现该功能:
def fn(i): fn.f += i return fn.f fn.f = 1
这绝对会落入频谱的"滥用"端.
你可以用JavaScript的方式做对象...它没有任何意义,但它有效;)
>>> def FakeObject(): ... def test(): ... print "foo" ... FakeObject.test = test ... return FakeObject >>> x = FakeObject() >>> x.test() foo
我谨慎使用它们,但它们可以非常方便:
def log(msg): log.logfile.write(msg)
现在我可以log
在整个模块中使用,只需通过设置重定向输出log.logfile
.有很多其他方法可以实现这一点,但这个轻量级,简单易用.虽然我第一次做它时闻起来很有趣,但我开始相信它比拥有全局logfile
变量更好闻.
函数属性可用于编写轻量级闭包,将代码和相关数据包装在一起:
#!/usr/bin/env python SW_DELTA = 0 SW_MARK = 1 SW_BASE = 2 def stopwatch(): import time def _sw( action = SW_DELTA ): if action == SW_DELTA: return time.time() - _sw._time elif action == SW_MARK: _sw._time = time.time() return _sw._time elif action == SW_BASE: return _sw._time else: raise NotImplementedError _sw._time = time.time() # time of creation return _sw # test code sw=stopwatch() sw2=stopwatch() import os os.system("sleep 1") print sw() # defaults to "SW_DELTA" sw( SW_MARK ) os.system("sleep 2") print sw() print sw2()
1.00934004784
2.00644397736
3.01593494415