Pycharm对未解决的属性引用显示视觉警告。

36

我有两个类,看起来像这样:

class BaseClass:

    def the_dct(self):
        return self.THE_DCT


class Kid(BaseClass):

    THE_DCT = {'key': 'value'}


# Code i ll be running
inst = Kid()
print(inst.the_dct())

继承必须按照这种方式进行; 第二个类包含THE_DCT和第一个类包含def the_dct

它工作得很好,但我的问题是,在 PyCharm 中我会收到一个警告(未解决的属性引用),关于BaseClass中的THE_DCT

  • 有没有什么原因它在警告我(例如为什么我应该避免它)?
  • 我应该做些什么不同的事情吗?

6
“为什么它在警告我?”- 因为在BaseClass中没有THE_DCT字典。 “我应该有所不同吗?”- 你可以在BaseClass中包含一个空字典THE_DCT = {},或者忽略这个警告。 - jonrsharpe
PyCharm经常会警告那些可以运行的代码,不过对于代码检查来说,存在着一定的限制(通常是由于预算和时间等方面的原因)。 - NDevox
1
@Scironic 这个具体的实现会起作用,但是 PyCharm 警告因为例如 BaseClass().the_dct() 会失败。 - jonrsharpe
1
只要程序能够正常运行(且易于阅读),就没有真正的危险。 - NDevox
4
只要您清晰记录BaseClass不应该直接实例化,这就不是问题。您还可以查看抽象基类 - jonrsharpe
显示剩余2条评论
3个回答

26
BaseClass 中,您引用了 self.THE_DCT,但是当 PyCharm 查看这个类时,它发现 THE_DCT 不存在。
假设您把它视为抽象类,PyCharm 不知道您的意图。它只看到一个类访问一个不存在的属性,因此显示警告。
尽管您的代码可以完美运行(只要您不实例化BaseClass),但您应该将其改为:
class BaseClass(object):
    THE_DCT = {}

    def the_dct(self):
        return self.THE_DCT

2
你真的应该把它改成什么?如果我不改变它,我会遇到哪些问题?此外,在BaseClass中定义THE_DCT会不会降低性能(或许是微小的)并且是不必要的? - user
21
这与性能无关。永远不要因为“性能”而编写糟糕的代码。 - dursk
1
我明白我应该避免过早优化,但我很好奇它是否会产生影响(即使是微小的)。 附:(和性能相关的问题与我的主题无关) - user
6
好的。不要编写依赖继承来查找未定义变量的代码,这是非常糟糕的做法。将变量定义为占位符,并注释说明继承如何替换这种定义。@Fermiparadox - user4396006
这会导致一个类级别(又称静态)属性被添加到基类以及实例属性中。除了这是浪费的,因为不应该使用类级别属性,它还容易出错,因为现在在同一对象上有两个具有不同值的对象(比较self.THE_DCT和在@classmethod中你有cls.THE_DCT或在常规方法中self.__classs__.THE_DCT)。 - Motti

9

除了现有的答案之外,或者作为一种替代方案,您可以使用Type Hints。这样可以满足PyCharm的警告,并将属性区分为继承的属性(或至少不是类本身的原生属性)。只需在类的顶部(任何其他内容之前)添加THE_DCT: dict即可。

class BaseClass(object):
    THE_DCT: dict  # Add a type-hint at the top of the class, before anything else

    def the_dct(self):
        return self.THE_DCT


class Kid(BaseClass):
    THE_DCT = {'vars': 'values'}

我喜欢这种方法,因为它避免了不必要地添加一个占位符属性(self.THE_DCT = {})。由于它在视觉上与声明属性不同,它也可以避免需要在占位符属性旁边添加注释来解释其继承的情况。

我认为类型提示是处理这些警告的最佳方式。 - Rob

0
继承必须是这样的:第二类包含THE_DCT,第一类包含def the_dct。
我认为这在概念上是错误的:基类不能使用(知道)子类中的字段(方法)。
这在Python中能够工作,真是令人难以置信。 :)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接