使用__getattr__和__slots__进行合成时,避免Pycharm __dict__查找

问题描述

我有一堂课:

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中分配它们。 (有效)

获取属性代码应:

  • 如果请求插槽中的任何内容(正常),请照常操作
  • 从_attrs中获取值(如果_attrs.keys()存在)(有效)
  • 在任何其他情况下(通常)(出现问题)都出错。

对于这个问题,我希望该错误模仿一个不存在对象属性的情况下通常会发生的情况。目前,在运行代码时,我在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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...