修改内置函数
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 类型。
让我们考虑任何用户定义的 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 类型。