如何使用“ next_in_line”代替“ super”

时间:2019-07-28 20:25:47

标签: python python-3.x super

Raymond Hettinger在对Super considered super!的精彩演讲中提到,他认为“ super”是“ super”的坏名字,我们应该更多地将其视为“ next inline”。 就像其他许多会听这个演讲的人一样,我也觉得这很有意义。

因此,在我自己的代码中,我在考虑是否可以在每次要调用“ 行内下一个”时使用其他名称/句柄,而不是使用super。 我正在考虑使用句柄:“ next_in_line ”,因为它是替换的直观名称!

我了解如果在任何其他导入的软件包中使用此名称,则可能发生潜在的冲突。但是在使用Python进行探索/学习时,我并不担心。

所以,我的问题是:我应该如何在中心位置实现这一目标?

以雷蒙德(Raymond)相关的blog post

为例
class LoggingDict(dict):
    def __setitem__(self, key, value):
        print(f'Setting key {key} to {value}')
        super().__setitem__(key, value)

我希望能够这样做:

class LoggingDict(dict):
    def __setitem__(self, key, value):
        print(f'Setting key {key} to {value}')
        next_in_line().__setitem__(key, value)

编辑1

尽管要在一个地方而不是在每个模块中进行此操作,但以下情况也会导致错误:

next_in_line = super

class LoggingDict(dict):
    def __setitem__(self, key, value):
        print(f'Setting key {key} to {value}')
        next_in_line().__setitem__(key, value)

ld = LoggingDict()
ld[1] = 'a'

输出:

Setting key 1 to a
Traceback (most recent call last):
  File "D:/pyth/logging_dict.py", line 9, in <module>
    ld[1] = 'a'
  File "D:/pyth/logging_dict.py", line 6, in __setitem__
    next_in_line().__setitem__(key, value)
RuntimeError: super(): __class__ cell not found

1 个答案:

答案 0 :(得分:2)

警告:不要这样做! super关键字是Python语言的一部分。如果您不喜欢它,请分叉该语言,并尝试说服其他程序员跟随您。否则,您的代码将对您(甚至对您)以外的所有人都难以理解。

现在您已经得到警告...您可以使用super的显式形式:

next_in_line = super

class LoggingDict(dict):
    def __setitem__(self, key, value):
        print(f'Setting key {key} to {value}')
        next_in_line(LoggingDict, self).__setitem__(key, value)

或者您可以在装饰器中修改函数的__globals__属性:

def next_in_line(func):
    def inner(self, *args, **kwargs):
        def nel(t=type(self), o=self):
            return super(t, o)
        func.__globals__["next_in_line"] = nel
        func(self, *args, **kwargs)

    return inner


class LoggingDict(dict):
    @next_in_line
    def __setitem__(self, key, value):
        print(f'Setting key {key} to {value}')
        next_in_line().__setitem__(key, value)

但同样,不要那样做。