5

有没有好的(适合在实际项目中使用)方法或减少类似这样的样板

class B(A):
    def qqq(self): # 1 unwanted token "self"
        super(B, self).qqq() # 7 unwanted tokens plus 2 duplications ("B", "qqq")
        do_something()

我希望它看起来更像这样:

class B(A):
    def qqq:
        super
        do_something()

或(更现实地)

class B(A):
    @autosuper_before
    def qqq(self):
        do_something()

在 Python 2.6+ 中是否有可能没有公开的黑客攻击?

没有参数的 Python 2.x 中的@link super()

4

1 回答 1

4

tl;博士

正如 OP 所说“在 Python 2.6+ 中是否有可能没有公开的黑客攻击?”,答案是:

长版

您可以制作一个简单的装饰器,该装饰器将使用此方法调用下一个父级。问题是您无法控制要传递的参数。

编辑: 这对于已经使用的子类不起作用,autosuper因为它会选择错误的类并进行无限循环。

def autosuper(fn):
    def f(self, *args, **kw):
        cl = super(type(self), self)
        getattr(cl, fn.__name__)(*args, **kw)
        return fn(self, *args, **kw)
    return f

怎么可能做到这一点?Python 3.x 确实有一个super不带参数的函数!

不幸的是,Python 3.xsuper是一个,同时也是一个关键字,因为它的名称的存在将改变当前环境,以揭示一个名为的变量__class__,它是您需要使用的正确类!

如果检查类中声明的函数内的框架,则没有__class__变量,并且co_freevars框架属性的f_code属性为空。当你写名字时super(不需要调用它),__class__字符串会出现,co_freevars意思是它来自另一个闭包。此外,如果您尝试在__class__不使用 super 的情况下访问变量,它将LOAD_DEFER出于同样的原因使用字节码,而不是LOAD_GLOBAL像每个未定义名称一样正常。

这太疯狂了,你不能只做不带参数的hyper = super调用这个新hyper变量(与 完全相同的对象super)。

因为我无法在 Python 解释器中与这么多的黑魔法竞争,而且因为autosuper装饰器没有在类中声明(所以__class__即使在 Python 2.x 中可能,它也永远无法访问变量),我不会尝试写一个新的装饰器,并将这个答案留在这里作为对其他想要这样做的人的警告。

可能有可能让一些黑客找到合适的类来使用,但我不会深入挖掘。需要考虑的事项:

  • 应用装饰器时,该类尚不存在,因此应在调用装饰函数时完成。
  • 被装饰的函数还不是一个unbound method(无论如何都从 Py3k 中删除了),所以你不能检查im_class属性。
  • The frame does not seem to hold any information of the class used to make this call (unless of course the __class__ variable do exist and it is possible to get a reference to it)
  • This answer provided by OP is also quite broken because it makes a lot of bad assumptions and has problems with decorated functions.
于 2012-08-04T23:48:58.957 回答