2

我正在编写一个框架,供了解一些 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__方法时,属性字典只包含一个 key f。我的想法是使用另一个装饰器,例如@duplicate让用户表示正在发生这种情况,并且两者f的包装方式不同,因此它们不会相互覆盖。像这样的东西可以工作吗?

4

3 回答 3

1

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

听从“Python 之禅”的建议:

命名空间是一个很棒的想法——让我们做更多的事情!

于 2012-10-26T20:54:18.970 回答
1

是的,您可以,但只能使用丑陋的 hack,并且只能使用名称存储函数。

您必须使用该sys._getframe()函数来检索调用框架的本地命名空间。该本地命名空间是构造中的类,将项目添加到该命名空间意味着它们最终将出现在传递给您的元类的类字典中。

以下检索该命名空间:

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

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

于 2012-10-26T20:54:46.003 回答
0

你可能在想 Java——方法重载和参数签名——但这是 Python,你不能这样做。第二个 f() 将覆盖第一个 f(),最后你只得到一个 f()。命名空间是一个字典,你不能有重复的键。

于 2012-10-26T20:54:51.600 回答