Testing whether class variable is repeatedly defined
下面是一个简单的例子:
1 2 3 4
| class KEY(object):
A = 'a'
A = 'b'
B = 'b' |
有没有一种方法可以测试"a"是否已在类"key"中重复定义,而不管赋值如何?
- 这可能不是您所需要的,但大多数IDE/代码分析器都会指出这一点。
- @ThomasOrozco感谢您的建议,但我需要在单元测试套件中进行运行时检查。
- 然后,也许使用元类可以做到这一点,但我认为不会。编辑:事实上,它不会。当变量到达元类代码时,它们已经被转换为字典(因此,重复项被删除)。
- 覆盖__new__会起作用吗?或者这是事先就发生的?抱歉,我不太熟悉底层的python"类加载"过程,我觉得我不应该在__import__上工作。
- @Thomasorozco:实际上,python 3确实为taht用例提供了一个条款。一个可以有一个__prepare__方法,它可以使类解析使用am-ordered dict或其他一些专门的映射。
如果您使用的是python 3,那么可以使用一个只允许设置不存在的键和元类的__prepare__方法的dict子类来完成这项工作。更多信息。在Python2中,这很难实现;我编写了一个可怕的黑客程序来实现它,但有一些限制。
- 我不知道Python3中的这个新方法,这是一个很好的答案!
下面是一个尝试的答案:
类变量不起作用
你不能控制这些的重新定义。基本上,metaclass是创建类的调用,它通过了attribute=>value的dict。我们可以说"已经太迟了"。
使用实例变量
您可以控制在类实例化后执行a.b = c时发生的情况,因此您可以执行以下操作:
1 2 3 4 5 6 7 8 9 10 11
| class RedefinitionMixin(object):
def __setattr__(self, k, v):
if hasattr(self, k):
raise Exception('Attribute redefinition!')
super(RedefinitionMixin, self).__setattr__(k, v)
class KEY(RedefinitionMixin, object):
def __init__(self):
self.A = 'a'
self.A = 'b'
self.B = 'b' |
但是,如果您已经覆盖了__setattr__,这可能会导致一些意外的行为!
注意,这只在实际实例化类的情况下有效。为了避免使用实例的问题,您可以实现一个singleton模式。
总的来说,我不推荐这个解决方案,但这是我现在能想到的最好的解决方案。
- +1为了说明"类变量不起作用"的原因,另一种方法是通过使用inspect.getsource对类进行静态分析,并检查类中每个变量名的外观,尽管与pylint相比,这没有什么区别。
- 刚刚尝试过,实际上pylint认为重新定义的类变量是一个有效的例子。