在更新“常量”时引发异常python 中的属性
由于python没有常量的概念,如果更新“常量”属性是否可能引发异常?如何?
class MyClass():
CLASS_CONSTANT = 'This is a constant'
var = 'This is a not a constant, can be updated'
#this should raise an exception
MyClass.CLASS_CONSTANT = 'No, this cannot be updated, will raise an exception'
#this should not raise an exception
MyClass.var = 'updating this is fine'
#this also should raise an exception
MyClass().CLASS_CONSTANT = 'No, this cannot be updated, will raise an exception'
#this should not raise an exception
MyClass().var = 'updating this is fine'
任何将 CLASS_CONSTANT 更改为类属性或实例属性的尝试都应该引发异常。
将 var 更改为类属性或实例属性不应引发异常。
As python does not have concept of constants, would it be possible to raise an exception if an 'constant' attribute is updated? How?
class MyClass():
CLASS_CONSTANT = 'This is a constant'
var = 'This is a not a constant, can be updated'
#this should raise an exception
MyClass.CLASS_CONSTANT = 'No, this cannot be updated, will raise an exception'
#this should not raise an exception
MyClass.var = 'updating this is fine'
#this also should raise an exception
MyClass().CLASS_CONSTANT = 'No, this cannot be updated, will raise an exception'
#this should not raise an exception
MyClass().var = 'updating this is fine'
Any attempt to change CLASS_CONSTANT as a class attribute or as an instance attribute should raise an exception.
Changing var as a class attribute or as an instance attribute should not raise an exception.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
如果您确实想要无法更改的常量,请查看以下内容: http://code .activestate.com/recipes/65207/
If you really want to have constant that can't be changed then look at this: http://code.activestate.com/recipes/65207/
开始阅读:
http://docs.python.org/reference/ datamodel.html#customizing-attribute-access
您基本上编写了自己的
__setattr__
版本,它会引发某些属性的异常,但不会引发其他属性的异常。Start reading this:
http://docs.python.org/reference/datamodel.html#customizing-attribute-access
You basically write your own version of
__setattr__
that throws exceptions for some attributes, but not others.在每个类中自定义
__setattr__
(例如,如 @ainab 的答案所指向的我的旧食谱以及其他答案中所示例的),只能停止分配给 INSTANCE 属性而不是 CLASS 属性。因此,现有的答案都不能真正满足您所述的要求。如果您要求的实际上正是您想要的,您可以诉诸自定义元类和描述符的某种组合,例如:
这是非常高级的东西,因此您可能更喜欢中建议的更简单的
__setattr__
方法其他答案,尽管它不符合您所述的要求(即,您可能会合理地选择削弱您的要求以获得简单性;-)。但这里的技术可能仍然很有趣:自定义描述符类型const
是另一种方式(恕我直言,比在每个需要一些常量的类中覆盖__setattr__
好得多,并且使所有属性常量而不是挑选和选择...)来阻止对实例属性的赋值;代码的其余部分是关于自定义元类创建其自身独特的每类子元类,以便充分利用所述自定义描述符并实现您特别要求的确切功能。Customizing
__setattr__
in every class (e.g. as exemplified in my old recipe that @ainab's answer is pointing to, and other answers), only works to stop assignment to INSTANCE attributes and not to CLASS attributes. So, none of the existing answers would actually satisfy your requirement as stated.If what you asked for IS actually exactly what you want, you could resort to some mix of custom metaclasses and descriptors, such as:
This is pretty advanced stuff, so you might prefer the simpler
__setattr__
approach suggested in other answers, despite it NOT meeting your requirements as stated (i.e., you might reasonably choose to weaken your requirements in order to gain simplicity;-). But the techniques here might still be interesting: the custom descriptor typeconst
is another way (IMHO far nicer than overriding__setattr__
in each and every class that needs some constants AND making all attributes constants rather than picking and choosing...) to block assignment to an instance attribute; the rest of the code is about a custom metaclass creating unique per-class sub-metaclasses of itself, in order to exploit said custom descriptor to the fullest and achieving the exact functionality you specifically asked for.你可以这样做:
(来自http://www.siafoo.net/snippet/108)
然后像这样使用它这:
You could do something like this:
(from http://www.siafoo.net/snippet/108)
Then use it like this:
您可以使用元类来实现此目的:
但是您确定这是一个真正的问题吗?您真的不小心到处设置常量吗?您可以使用 grep -r '\.[AZ][A-Z0-9_]*\s*=' src/ 轻松找到其中的大部分内容。
You can use a metaclass to achieve this:
But are you sure this is a real issue? Are you really accidentally setting constants all over the place? You can find most of these pretty easily with a
grep -r '\.[A-Z][A-Z0-9_]*\s*=' src/
.