【发布时间】:2016-08-15 16:38:33
【问题描述】:
我使用这个逻辑来维护Object 实例的有向树:
class Object:
def __init__(self, *parents: 'Object'):
self.__parents = list(parents)
@property
def __ascendants(self):
for parent in self.__parents:
yield from parent.__ascendants
yield parent
这段代码运行良好,但 PyLint 抱怨 __ascendants 是 parent 的受保护成员,对于 PyLint 来说,这是一个客户端类。
对于受保护的、未损坏的成员,这很好:我不应该访问这样的成员,因为它们可能会被 Object 子类覆盖。
但在这种情况下,由于属性被破坏,子类不可能覆盖它们,这就是为什么我允许自己甚至在外部对象上使用它们(提供给构造函数)。
TLDR ;我正在寻找一种方法让 PyLint 接受访问客户端子类的损坏属性,而不必每次都求助于#pylint: disable=protected-access,或者全局禁用警告。
看起来我可以使用astng 回调来注册MANAGER,并转换一个模块,以便PyLint 可以使用其他信息。但是,我只能添加存根成员(以便可以在没有警告的情况下使用动态添加的成员),我不确定我是否可以通过这种方式解决我的问题。
我也尝试添加assert isinstance(parent, Object),但无济于事。
编辑:
我能够编写代码使 PyLInt 不会引发 protected-access,而只会引发 bad-staticmethod-argument。我没有在这个特定的类中使用其他 staticmethod ,所以也许这是这个问题的一个可接受的答案:
class Object:
def __init__(self, *parents: 'Object'):
self.__parents = list(parents)
@staticmethod
def __get_ascendants(self: 'Object'):
for parent in self.__parents:
yield from self.__get_ascendants(parent)
yield parent
编辑 2:(灵感来自 @shx2)
使用具有正确参数名称的 lambda 也会愚弄 Pylint:
class Object:
def __init__(self, *parents: 'Object'):
self.__parents = list(parents)
@property
def __ascendants(self):
get_ascendants = lambda self: self.__ascendants
for parent in self.__parents:
yield from get_ascendants(parent)
yield parent
编辑 3:因为名称不会从生成器表达式(或列表 omprehensions)中泄漏出来,所以也可以这样写:
from itertools import chain
class Object:
def __init__(self, *parents: 'Object'):
self.__parents = list(parents)
@property
def __ascendants(self):
return chain(*(
chain(self.__ascendants, (self, ))
for self in self.__parents
))
【问题讨论】:
标签: python oop code-analysis pylint private-members