在Python中,使用相同的名称修饰两个方法以区分它们

时间:2012-10-26 20:50:09

标签: python decorator metaclass

我正在编写一个框架供知道某些python的人使用。我已经确定了一些语法,我和他们使用类似的东西是有意义的,其中Base是实现框架的Base类。

class A(Base):
    @decorator1
    @decorator2
    @decorator3
    def f(self):
        pass

    @decorator4
    def f(self):
        pass

    @decorator5
    def g(self)
        pass

我的所有框架都是通过Base的元类实现的。此设置适用于我的用例,因为所有这些用户定义的类都具有丰富的继承图。我希望用户实现一些方法,或者只留下pass。用户在这里提供的大部分信息都在装饰器中。这使我可以避免其他解决方案,用户必须使用猴子补丁,提供结构较少的字典,以及类似的东西。

我的问题是f由用户定义两次(有充分理由),这应该由我的框架处理。不幸的是,当它到达元类“__new__方法时,属性字典只包含一个键f。我的想法是使用另一个装饰器,例如@duplicate,以便用户发出信号,并且两个f的包装方式不同,因此它们不会相互覆盖。像这样的东西能起作用吗?

3 个答案:

答案 0 :(得分:1)

您应该使用命名空间来区分不同的f

听取了“禅宗蟒蛇”的建议:

  

命名空间是一个很好的主意 - 让我们做更多的事情!

答案 1 :(得分:1)

是的,您可以,但只能使用丑陋的黑客攻击,并且只能使用 new 名称存储该功能。

您必须使用sys._getframe() function来检索调用帧的本地命名空间。该本地命名空间是构造类,并且向该命名空间添加项目意味着它们最终会传递到传递给您的元类的类字典中。

以下内容检索该命名空间:

callframe = sys._getframe(1)
namespace = callframe.f_locals

namespace是一个类似dict的对象,就像locals()一样。您现在可以在该命名空间中存储某些内容(如__function_definitions__或类似内容)以添加对函数的额外引用。

答案 2 :(得分:0)

你可能会想到java - 方法重载和参数签名 - 但这是python,你不能这样做。第二个f()将覆盖第一个f(),最后只有一个f()。命名空间是一个字典,您不能拥有重复的密钥。