我使用此逻辑来维护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
。我不会在这个特定的课程中使用其他静态方法,所以这可能是这个问题的可接受的答案:
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
))
答案 0 :(得分:1)
为什么要将ascendants
方法设为受损属性?如果您真的想要使用这样一个复杂的继承并为每个超类保留多个parents
属性,那么修改parents
将起作用。但是,似乎没有用于修改ascendants
函数,因为它属于类,而不属于对象本身:
class Object(object):
def __init__(self, parents):
self.__parents = list(parents)
def ascendants(self):
for parent in self.__parents:
yield from parent.ascendants()
yield parent
答案 1 :(得分:1)
我正在寻找一种让PyLint接受访问客户端子类的受损属性的方法
有愚弄pylint的方法。
一种方法是将parent
伪装成self
:
@property
def __ascendants(self):
for parent in self.__parents:
self = parent
yield from self.__ascendants
yield self
另一个是使用getattr
间接访问该属性。而不是:
yield from parent.__ascendants
做的:
yield from getattr(parent, '__ascendants')