【问题标题】:Modifying built-in function修改内置函数
【发布时间】:2016-01-05 15:54:25
【问题描述】:

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

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

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

  • 内置属性,
  • 用户定义。

我需要覆盖__dir__,以便它只返回用户定义的属性。我怎么能这样做?

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

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

但要避免无限递归。

一般来说,如果我不想从头编写,但想修改现有函数,如何修改内置函数?

【问题讨论】:

  • 您是否尝试改用dir(ClassName)

标签: python python-3.x overriding built-in


【解决方案1】:

使用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']

【讨论】:

  • 为什么使用生成器比使用list(filter...))更好?
  • @VeLKerr,它不是生成器,而是列表理解。对我来说,它更容易阅读。
  • 好的,它正在工作,但很奇怪,因为super()-object 没有用户定义的字段。那么,您能否解释一下,为什么它有效?
  • @VeLKerr,请点击链接回答。 super.
【解决方案2】:

您想在您的自定义类上还是在全局范围内为dir() 函数执行此操作?

第一种方法(仅限类):

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'] 

基本上这里所做的是调用超类(不是类本身)的__dir__() 并在子类中过滤它。

第二种方法(阴影全局目录功能):

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() 的调用。如您所见 - 它适用于所有类型,包括内置类型。

【讨论】:

  • 我只想为我的班级覆盖__dir()__,但非常感谢您对全局阴影的解释。附言super() 即使没有参数也对我有用(我编辑了帖子)。
猜你喜欢
  • 1970-01-01
  • 2019-01-02
  • 2019-10-25
  • 2013-02-18
  • 2021-09-24
  • 1970-01-01
  • 2013-10-24
  • 1970-01-01
  • 2015-01-31
相关资源
最近更新 更多