访问另一个实例的损坏成员
Accessing mangled member of another instance
我使用这个逻辑来维护 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 而言,客户端 class.
如果是受保护的、未损坏的成员,那就没问题了:我不应该访问这样的成员,因为它们可能会被 Object
subclass.
但在这种情况下,由于属性被破坏,子class不可能覆盖它们,这就是为什么我允许自己甚至在外部对象上使用它们(提供给构造函数) .
TLDR;我正在寻找一种方法让 PyLint 接受访问客户端子 class 的损坏属性,而不必每次都求助于 #pylint: disable=protected-access
,或全局禁用警告。
看来我可以使用 astng
回调来注册一个 MANAGER
,并转换一个模块,以便 PyLint 可以使用其他信息。但是,我只能添加存根成员(以便可以在没有警告的情况下使用动态添加的成员),我不确定我是否可以通过这种方式解决我的问题。
我也试过添加assert isinstance(parent, Object)
,但没有用。
编辑 :
我能够编写代码,使 PyLInt 不会引发 protected-access
,而只会引发 bad-staticmethod-argument
。我没有在这个特定的 class 中使用其他 staticmethod s,所以也许这可能是这个问题的一个可接受的答案:
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
))
为什么要使 ascendants
方法成为一个损坏的 属性?如果你真的想使用如此复杂的继承并为每个 superclasses 保留多个 parents
属性,则 mangling parents
将起作用。但是,似乎在 mangling ascendants
函数中没有用,因为它属于 class,而不属于对象本身:
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
I'm looking for a way to make PyLint accept accessing mangled attributes of a client subclass
有办法骗过 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')
我使用这个逻辑来维护 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 而言,客户端 class.
如果是受保护的、未损坏的成员,那就没问题了:我不应该访问这样的成员,因为它们可能会被 Object
subclass.
但在这种情况下,由于属性被破坏,子class不可能覆盖它们,这就是为什么我允许自己甚至在外部对象上使用它们(提供给构造函数) .
TLDR;我正在寻找一种方法让 PyLint 接受访问客户端子 class 的损坏属性,而不必每次都求助于 #pylint: disable=protected-access
,或全局禁用警告。
看来我可以使用 astng
回调来注册一个 MANAGER
,并转换一个模块,以便 PyLint 可以使用其他信息。但是,我只能添加存根成员(以便可以在没有警告的情况下使用动态添加的成员),我不确定我是否可以通过这种方式解决我的问题。
我也试过添加assert isinstance(parent, Object)
,但没有用。
编辑 :
我能够编写代码,使 PyLInt 不会引发 protected-access
,而只会引发 bad-staticmethod-argument
。我没有在这个特定的 class 中使用其他 staticmethod s,所以也许这可能是这个问题的一个可接受的答案:
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
))
为什么要使 ascendants
方法成为一个损坏的 属性?如果你真的想使用如此复杂的继承并为每个 superclasses 保留多个 parents
属性,则 mangling parents
将起作用。但是,似乎在 mangling ascendants
函数中没有用,因为它属于 class,而不属于对象本身:
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
I'm looking for a way to make PyLint accept accessing mangled attributes of a client subclass
有办法骗过 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')