如何让dir()函数不返回__init_subclass__?空类输出结果不符预期
问题描述
你创建了空的BaseGeometry类后,调用dir()得到的结果包含__init_subclass__方法,但预期结果不需要这个方法,具体对比如下:
[Got] ['class', 'delattr', 'dict', 'dir', 'doc', 'eq', 'format', 'ge', 'getattribute', 'gt', 'hash', 'init', 'init_subclass', 'le', 'lt', 'module', 'ne', 'new', 'reduce', 'reduce_ex', 'repr', 'setattr', 'sizeof', 'str', 'subclasshook', 'weakref', 'area']
[Expected] ['class', 'delattr', 'dict', 'dir', 'doc', 'eq', 'format', 'ge', 'getattribute', 'gt', 'hash', 'init', 'le', 'lt', 'module', 'ne', 'new', 'reduce', 'reduce_ex', 'repr', 'setattr', 'sizeof', 'str', 'subclasshook', 'weakref', 'area']
当前使用的代码:
#!/usr/bin/python3 """Module implementing BaseGeometry class""" class BaseGeometry: """Empty class""" pass
解决方案
__init_subclass__是Python 3.6+版本中object类自带的钩子方法,默认会出现在dir()的返回结果里。要过滤掉它,分两种场景处理:
1. 针对类实例的dir()调用
重写类的__dir__方法,在返回属性列表时移除__init_subclass__:
#!/usr/bin/python3 """Module implementing BaseGeometry class""" class BaseGeometry: """Empty class""" def __dir__(self): # 调用父类方法获取默认属性列表,过滤掉目标方法 default_attrs = super().__dir__() return [attr for attr in default_attrs if attr != '__init_subclass__']
2. 针对类本身的dir()调用
如果需要调用dir(BaseGeometry)时也不显示该方法,需要通过自定义元类来修改类的__dir__行为:
#!/usr/bin/python3 """Module implementing BaseGeometry class""" class NoInitSubclassMeta(type): def __dir__(cls): default_dir = super().__dir__() return [item for item in default_dir if item != '__init_subclass__'] class BaseGeometry(metaclass=NoInitSubclassMeta): """Empty class""" pass
以上两种方案分别对应实例和类本身的dir()调用需求,根据实际场景选择即可。
内容的提问来源于stack exchange,提问作者Ahmed Bousaleh

