__decorated__用于python装饰器

Eri*_*now 5 c python compiler-construction parsing decorator

从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__只返回原始的装饰函数.但是,如果装饰器返回原始函数,会发生什么?以下是我能想到的三个选项(第三个是我最喜欢的):

  1. 不要添加__decorator__.
  2. 添加__decorator__但将其设置为无.
  3. __decorator__无论如何,添加并将其设置为原始功能.

所以,如果它发生了,你认为最好的选择是什么?

更新:

其他人提请我注意我错过的情景.当装饰器既不返回原始函数也不返回包装原始函数的函数时会发生什么?那时没有任何东西持有对原始函数的引用,它将被垃圾收集.(感谢Oddthinking!)

那么在那种情况下,我认为我仍然会选择第三种方案.装饰器返回的对象将获得一个__decorated__引用原始函数的名称.这意味着它不会被垃圾收集.

对我来说,类定义中的函数完全消失是因为你装饰它,这似乎很奇怪.在我看来,更有理由__decorated__为每个装饰者申请一个属性.然而,我的直觉更有可能是错误的,并且当前的行为是大多数人所期望的. 有什么想法吗?

ps这是我早期更普遍的问题的延伸.我还通过单独的帖子了解了第一部分的更多信息.

Dav*_*d Z 2

好吧,无论这是否是一个好主意,我都会选择选项#3,因为它是最一致的:它总是显示该函数已通过属性的存在进行了修饰,并访问了属性始终返回一个函数,因此您不必针对None.

不过,您还应该考虑这一点:您建议对手动装饰做什么?例如

def test(first): pass
test = d(test)
Run Code Online (Sandbox Code Playgroud)

关于问题的第一部分,我没有太多地查看Python解释器源代码,所以我无法向您指出任何特别有用的东西。