gri*_*yvp 19 python exception descriptor readonly-attribute
我想在python中创建一个具有一些属性的对象,我想保护自己不会意外使用错误的属性名称.代码如下:
class MyClass( object ) :
m = None # my attribute
__slots__ = ( "m" ) # ensure that object has no _m etc
a = MyClass() # create one
a.m = "?" # here is a PROBLEM
Run Code Online (Sandbox Code Playgroud)
但运行这个简单的代码后,我得到一个非常奇怪的错误:
Traceback (most recent call last):
File "test.py", line 8, in <module>
a.m = "?"
AttributeError: 'test' object attribute 'm' is read-only
Run Code Online (Sandbox Code Playgroud)
有没有明智的程序员能够节省一些时间并让我了解"只读"错误?
Aym*_*ieh 43
使用声明实例变量时__slots__,Python会将描述符对象创建为具有相同名称的类变量.在您的情况下,此描述符将被m您在以下行定义的类变量覆盖:
m = None # my attribute
Run Code Online (Sandbox Code Playgroud)
以下是您需要做的事情:不要定义一个名为的变量m,并m在__init__方法中初始化实例变量.
class MyClass(object):
__slots__ = ("m",)
def __init__(self):
self.m = None
a = MyClass()
a.m = "?"
Run Code Online (Sandbox Code Playgroud)
作为旁注,具有单个元素的元组在元素之后需要逗号.两者都适用于您的代码,因为它__slots__接受单个字符串或可迭代/字符串序列.通常,要定义包含元素的元组1,请使用(1,)或1,不使用(1).
nik*_*kow 14
你完全是在滥用__slots__.它会阻止__dict__为实例创建.这只有在遇到许多小对象的内存问题时才有意义,因为摆脱__dict__可以减少占用空间.这是99.9%的情况下不需要的核心优化.
如果您需要您所描述的那种安全性,那么Python确实是错误的语言.更好地使用像Java这样严格的东西(而不是尝试用Python编写Java).
如果你无法弄清楚为什么类属性在你的代码中引起了这些问题,那么你可能应该三思而行,就像这样引入语言黑客.首先要更熟悉这门语言可能会更明智.
__slots__使用实例变量,而你拥有的是一个类变量.这就是你应该这样做的方式:
class MyClass( object ) :
__slots__ = ( "m", )
def __init__(self):
self.m = None
a = MyClass()
a.m = "?" # No error
Run Code Online (Sandbox Code Playgroud)
考虑一下.
class SuperSafe( object ):
allowed= ( "this", "that" )
def __init__( self ):
self.this= None
self.that= None
def __setattr__( self, attr, value ):
if attr not in self.allowed:
raise Exception( "No such attribute: %s" % (attr,) )
super( SuperSafe, self ).__setattr__( attr, value )
Run Code Online (Sandbox Code Playgroud)
更好的方法是使用单元测试进行此类检查.这是一个相当大的运行时间开销.
| 归档时间: |
|
| 查看次数: |
15632 次 |
| 最近记录: |