问题描述
说我有一堂课:
class Example:
__slots__ = ("_attrs","other_value")
def __init__(self):
self._attrs = OrderedDict()
self.other_value = 1
self.attribute = 0
def __setattr__(self,key,value):
if key in self.__slots__:
return super().__setattr__(key,value)
else:
self._attrs[key] = value
def __getattr__(self,key):
return self._attrs[key]
目标是使Example具有两个位置:
- 如果已设置,则照常进行设置。 (有效)
- 如果设置了其他属性,请在_attrs中分配它们。 (有效)
对于这个问题,我希望该错误模仿一个不存在对象属性的情况下通常会发生的情况。目前,在运行代码时,我在self._attrs上遇到关键错误。尽管这很好,但将其隐藏起来会很好。更烦人的是,如果我在Pycharm中进行调试,则自动完成功能会在尝试输入 dict 之前就排除了一个大错误,甚至我还没有按下Enter键即可:
Example().abc # hit tab in pycharm
# returns the error:
Traceback (most recent call last):
File "/Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_comm.py",line 1464,in do_it
def do_it(self,dbg):
File "/Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydev_bundle/_pydev_completer.py",line 159,in generate_completions_as_xml
def generate_completions_as_xml(frame,act_tok):
File "/Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydev_bundle/_pydev_completer.py",line 77,in complete
def complete(self,text):
File "/Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydev_bundle/_pydev_completer.py",line 119,in attr_matches
def attr_matches(self,text):
File "/Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydev_bundle/_pydev_imports_tipper.py",line 165,in generate_imports_tip_for_module
def generate_imports_tip_for_module(obj_to_complete,dir_comps=None,getattr=getattr,filter=lambda name:True):
File "/Users/xxxxxxxxx/",line 46,in __getattr__
def __getattr__(self,key: str) -> None:
KeyError: '__dict__'
有没有办法通过不同的代码来抑制这种情况?
解决方法
您可能可以通过实施__dir__
on the class,so it has a canonical source of names that can be completed使其起作用:
def __dir__(self):
return 'other_value',*self._attrs.keys()
我不敢保证PyCharm如何实现他们的制表符补全,因此无法保证它能起作用,但这是为类型定义可枚举属性集的方法,希望PyCharm会在可用时使用它。而不是__dict__
。
另一种方法(无论如何都可能是个好主意),以确保在__getattr__
失败时引发正确的错误,因此PyCharm知道问题是缺少属性,而不是{{ 1}}:
dict