修改内置函数

Modifying built-in function

让我们考虑任何用户定义的 pythonic class。如果我调用 dir(obect_of_class),我会得到它的属性列表:

['__class__', '__delattr__', '__dict__', '__dir__', ... '__weakref__', 'bases', 
'build_full_name', 'candidates', ... 'update_name'].

您可以在此列表中看到 2 种类型的属性:

我需要重写 __dir__,这样它 return 只会是用户定义的属性。我该怎么做?

很明显,如果在覆盖的函数中调用自身,它会给我无限递归。所以,我想做这样的事情:

def __dir__(self):
        return list(filter(lambda x: not re.match('__\S*__', x), dir(self)))

但避开无限递归。

一般来说,如果不想从头写一个内置函数,又想修改已有的函数,如何修改?

使用super调用父类的实现__dir__;避免递归:

import re


class AClass:

    def __dir__(self):
        return [x for x in super().__dir__() if not re.match(r'__\S+__$', x)]

    def method(self):
        pass

>>> dir(AClass())
['method']

你想在你的自定义 class 上还是在 dir() 函数中全局执行?

第一种方法(class-only):

class MyClass:
    def f(self):
        return None

    def __dir__(self):
        return list(filter(lambda x: not re.match('__\S*__', x), super().__dir__()))


print(dir(MyClass()))  # ['f'] 

基本上这里所做的是调用 superclass 的 __dir__()(不是 class 本身)并在 subclass.

中过滤它

第二种方法(隐藏全局目录函数):

import re


def dir(obj):
    return list(filter(lambda x: not re.match('__\S*__', x), __builtins__.dir(obj)))

print(dir({}))  # ['clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']

此处将过滤所有对 dir() 的调用。如您所见 - 它适用于所有类型,包括 built-in 类型。