【发布时间】:2016-06-29 15:43:24
【问题描述】:
想象一个函数,它动态地 使用setattr 向对象添加属性。这样做的原因是我想将一些外部结构(例如给定的参数树)映射到一个对象:
my_object = SomeClass()
apply_structure(my_object, some_descriptor)
my_object.device1.enabled = True
从技术上讲,这是可行的,但 Pylint 当然正确地抱怨 'device1' 不是SomeClass 的成员。
我可以禁用警告,但这会很糟糕(因为在所有情况下,当属性由于拼写错误等原因不存在时,我仍然希望得到警告)。
是否有一种常见且合法的(Pylint-proof)方法可以动态地将成员添加到不会导致警告的对象?
或者:我可以只为一个对象而不是一个行/块/文件禁用Pylint吗?
解释:
您可能想知道,当我计划稍后以硬编码的方式访问这些属性时,为什么要动态地为对象配备成员属性。
原因是:我有一个程序的动态部分(装饰发生的地方)和一个静态部分,它专门用于某个场景。所以我可以也为这个场景创建一个静态类,但在很多情况下这会是多余的。
以下专用代码可能允许访问可能连接到某些总线的设备的某些参数:
class MyDeviceHandler:
on_get_some_subtree_element(self):
return _some_internal_value
on_set_some_subtree_element(self, value):
_some_internal_value = value
dev = MyDeviceHandler()
decorate_object_with_device_structure(dev, 'some/attached/device')
dev.some.subtree.element = 5 <--- will call the set-callback
x = dev.some.subtree.element <--- will call the get-callback
所以'some/attached/device' 背后的结构可能是任意的并且非常复杂,我不想在类结构中重现它。
消除此警告的一种方法是创建/访问基于dict 的树:
dev['some']['subtree']['element'] = 5
但这更难写,也不好读——我这样做只是为了让 Pylint 安静。
【问题讨论】:
-
我的问题是,如果您事先知道要访问的结构,为什么不首先明确定义该结构?
-
这正是问题所在。我不知道。实际上,我从设备属性树(可以是任何东西)中读取了一个结构,然后构建了一个 Python 对象。我将在问题中进一步详细说明..
-
您可以设置
generated-members或ignored-classesoptions for pylint(在命令行上,或在[TYPECHECK]下.pylintrc) -
@TheCompiler 您应该将其添加为答案。
generated-members是我用例的解决方案。我有一个options单例,多个模块会向其中添加选项(和默认值)。选项单例封装了与解析命令行选项相关的行为。但是选项的名称和默认值仍然根据使用这些特定选项的模块进行组织。 -
--generated-members=MyEnum将错误静音Instance of 'str' has no 'value' memberpylint(no-member)