Eli*_*sky 181 python attributes function
没有多少人知道这个功能,但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
Run Code Online (Sandbox Code Playgroud)
Python中此功能的可能用途和滥用情况是什么?我知道的一个好用途是PLY使用docstring将语法规则与方法相关联.但是自定义属性呢?有充分的理由使用它们吗?
Mar*_*wis 142
我通常使用函数属性作为注释的存储.假设我想以C#的方式编写(表明某个方法应该是Web服务接口的一部分)
class Foo(WebService):
@webmethod
def bar(self, arg1, arg2):
...
Run Code Online (Sandbox Code Playgroud)
然后我可以定义
def webmethod(func):
func.is_webmethod = True
return func
Run Code Online (Sandbox Code Playgroud)
然后,当webservice调用到达时,我查找方法,检查底层函数是否具有is_webmethod属性(实际值是不相关的),如果方法不存在或者不打算通过Web调用,则拒绝服务.
mip*_*adi 118
我已经将它们用作函数的静态变量.例如,给出以下C代码:
int fn(int i)
{
static f = 1;
f += i;
return f;
}
Run Code Online (Sandbox Code Playgroud)
我可以在Python中类似地实现该功能:
def fn(i):
fn.f += i
return fn.f
fn.f = 1
Run Code Online (Sandbox Code Playgroud)
这绝对会落入频谱的"滥用"端.
def*_*ull 50
你可以用JavaScript的方式做对象...它没有任何意义,但它有效;)
>>> def FakeObject():
... def test():
... print "foo"
... FakeObject.test = test
... return FakeObject
>>> x = FakeObject()
>>> x.test()
foo
Run Code Online (Sandbox Code Playgroud)
Rob*_*ney 14
我谨慎使用它们,但它们可以非常方便:
def log(msg):
log.logfile.write(msg)
Run Code Online (Sandbox Code Playgroud)
现在我可以log在整个模块中使用,只需通过设置重定向输出log.logfile.有很多其他方法可以实现这一点,但这个轻量级,简单易用.虽然我第一次做它时闻起来很有趣,但我开始相信它比拥有全局logfile变量更好闻.
Kev*_*tle 10
函数属性可用于编写轻量级闭包,将代码和相关数据包装在一起:
#!/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()
Run Code Online (Sandbox Code Playgroud)
1.00934004784
2.00644397736
3.01593494415
Dio*_*ves 10
我创建了这个辅助装饰器来轻松设置函数属性:
def with_attrs(**func_attrs):
"""Set attributes in the decorated function, at definition time.
Only accepts keyword arguments.
E.g.:
@with_attrs(counter=0, something='boing')
def count_it():
count_it.counter += 1
print count_it.counter
print count_it.something
# Out:
# >>> 0
# >>> 'boing'
"""
def attr_decorator(fn):
@wraps(fn)
def wrapper(*args, **kwargs):
return fn(*args, **kwargs)
for attr, value in func_attrs.iteritems():
setattr(wrapper, attr, value)
return wrapper
return attr_decorator
Run Code Online (Sandbox Code Playgroud)
一个用例是创建工厂集合并查询它们可以在函数元级别创建的数据类型。
例如(非常愚蠢的):
@with_attrs(datatype=list)
def factory1():
return [1, 2, 3]
@with_attrs(datatype=SomeClass)
def factory2():
return SomeClass()
factories = [factory1, factory2]
def create(datatype):
for f in factories:
if f.datatype == datatype:
return f()
return None
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
102826 次 |
| 最近记录: |