有许多巧妙的项目正在扩展核心语言和标准库内外的python的实用性.一些想到的是:
有哪些项目让您兴奋不已,无论是在此列表中还是其中?
我希望能够问一个类的__init__方法它的参数是什么.直截了当的方法如下:
cls.__init__.__func__.__code__.co_varnames[:code.co_argcount]
Run Code Online (Sandbox Code Playgroud)
但是,如果类有任何装饰器,那将无效.它将给出装饰器返回的函数的参数列表.我想了解原始__init__方法并获取原始参数.在装饰器的情况下,装饰器函数将在装饰器返回的函数的闭包中找到:
cls.__init__.__func__.__closure__[0]
Run Code Online (Sandbox Code Playgroud)
但是,如果闭包中还有其他内容,装饰器可能会不时地执行此操作,则会更复杂:
def Something(test):
def decorator(func):
def newfunc(self):
stuff = test
return func(self)
return newfunc
return decorator
def test():
class Test(object):
@Something(4)
def something(self):
print Test
return Test
test().something.__func__.__closure__
(<cell at 0xb7ce7584: int object at 0x81b208c>, <cell at 0xb7ce7614: function object at 0xb7ce6994>)
Run Code Online (Sandbox Code Playgroud)
然后我必须决定是否要从装饰器的参数或原始函数的参数.由装饰返回的功能可能有*args和**kwargs它的参数.如果有多个装饰者,我必须决定哪个是我关心的?
那么即使函数可以被装饰,找到函数参数的最佳方法是什么?另外,将一系列装饰器放回装饰功能的最佳方法是什么?
更新:
这是我现在正在做的事情(名称已被更改以保护被告的身份):
import abc
import collections
IGNORED_PARAMS = ("self",)
DEFAULT_PARAM_MAPPING = {}
DEFAULT_DEFAULT_PARAMS = {}
class DICT_MAPPING_Placeholder(object):
def __get__(self, obj, type):
DICT_MAPPING = {} …Run Code Online (Sandbox Code Playgroud) (我使用的是python 2.7)python文档表明你可以将映射传递给内置的dict,它会将该映射复制到新的dict中:
http://docs.python.org/library/stdtypes.html#mapping-types-dict
我有一个实现Mapping ABC的类,但它失败了:
import collections
class Mapping(object):
def __init__(self, dict={}): self.dict=dict
def __iter__(self): return iter(self.dict)
def __iter__(self): return iter(self.dict)
def __len__(self): return len(self.dict)
def __contains__(self, value): return value in self.dict
def __getitem__(self, name): return self.dict[name]
m=Mapping({5:5})
dict(m)
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# TypeError: cannot convert dictionary update sequence element #0 to a sequence
collections.Mapping.register(Mapping)
dict(m)
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# …Run Code Online (Sandbox Code Playgroud) 从2.4(类的2.6)开始,python允许你用另一个函数来装饰一个函数:
def d(func): return func
@d
def test(first): pass
Run Code Online (Sandbox Code Playgroud)
这是一种方便的语法糖.您可以使用装饰器做各种各样的整洁的东西,而不会弄乱.但是,如果你想找出装饰的原始功能,你必须跳过箍(喜欢Cls.method.__func__.__closure__[0].cell_contents或更糟).
我发现自己希望有一个更好的方法,并发现在python-dev上有一些关于添加一个变量的讨论,该变量被称为__decorated__装饰器返回的[new]函数.然而,似乎没有去任何地方.
作为一个冒险的人,并且有大约4年的相当重的python经验,我想我会考虑__decorated__在python编译器源中实现,只是为了看看它是怎么回事.
说实话,我从来没有钻研过引擎盖下的C,所以我的第一个小时就是试图弄清楚底层C代码是如何工作的.首先,什么是最好的资源来了解我必须改变/添加的内容__decorator__?
其次,如果装饰器返回一个新函数,那么__decorated__只返回原始的装饰函数.但是,如果装饰器返回原始函数,会发生什么?以下是我能想到的三个选项(第三个是我最喜欢的):
__decorator__.__decorator__但将其设置为无.__decorator__无论如何,添加并将其设置为原始功能.所以,如果它发生了,你认为最好的选择是什么?
更新:
其他人提请我注意我错过的情景.当装饰器既不返回原始函数也不返回包装原始函数的函数时会发生什么?那时没有任何东西持有对原始函数的引用,它将被垃圾收集.(感谢Oddthinking!)
那么在那种情况下,我认为我仍然会选择第三种方案.装饰器返回的对象将获得一个__decorated__引用原始函数的名称.这意味着它不会被垃圾收集.
对我来说,类定义中的函数完全消失是因为你装饰它,这似乎很奇怪.在我看来,更有理由__decorated__为每个装饰者申请一个属性.然而,我的直觉更有可能是错误的,并且当前的行为是大多数人所期望的. 有什么想法吗?
python ×4
decorator ×2
c ×1
closures ×1
function ×1
parsing ×1
postgresql ×1
projects ×1
replication ×1
subclass ×1