Class 对象不适当地共享属性
Class Objects Inappropriately Sharing Attribute
我有一个带有属性的 class。最初它包含一条错误消息的单个字符串。我想我会变得聪明并将它变成一个列表,所以每次我 'set' 属性时,它不会替换字符串,而是将字符串附加到列表中。
但是,现在 err
属性在对象之间共享,而不是每个对象都是唯一的。
这是我的代码(test.py
,在这个例子中被删减到最小值)
#!/usr/bin/python3
# pylint: disable=C0301
'''Testing MyHost class'''
class MyHostGood: # pylint: disable=R0903
'''Host class'''
err = ''
name = ''
def __init__(self, name=''):
'''Constructor'''
self.name = name
def __str__(self):
'''Return a printable user representation of the object - print(x)'''
info = f'{self.name}:'
# These are error/warning messages
if self.err:
info += f'\n└ ERROR: {self.err}'
return info
class MyHostBad: # pylint: disable=R0903
'''Host class'''
_err = []
name = ''
def __init__(self, name=''):
'''Constructor'''
self.name = name
def __str__(self):
'''Return a printable user representation of the object - print(x)'''
info = f'{self.name}:'
# These are error/warning messages
if self._err:
for errMsg in self._err:
info += f'\n└ ERROR: {errMsg}'
return info
@property
def err(self):
'''Return the list of error messages'''
return self._err
@err.setter
def err(self, arg):
'''Add another string to the error messages'''
if isinstance(arg, str):
self._err.append(arg)
if isinstance(arg, list):
self._err.extend(arg)
这里是好的 class,其中 err
属性是独一无二的:
>>> import test
>>> a = test.MyHostGood('foo')
>>> a.err = 'Here is one error string'
>>> print(a)
foo:
└ ERROR: Here is one error string
>>> b = test.MyHostGood('bar')
>>> print(b)
bar:
>>> b.err = 'a new error'
>>> print(a)
foo:
└ ERROR: Here is one error string
>>> print(b)
bar:
└ ERROR: a new error
>>>
这里 err
属性现在在对象之间共享:
>>> import test
>>> c = test.MyHostBad('wiz')
>>> c.err = 'Here is one error string'
>>> print(c)
wiz:
└ ERROR: Here is one error string
>>> d = test.MyHostBad('baz')
>>> print(d)
baz:
└ ERROR: Here is one error string
>>> d.err = 'a new error'
>>> print(c)
wiz:
└ ERROR: Here is one error string
└ ERROR: a new error
>>> print(d)
baz:
└ ERROR: Here is one error string
└ ERROR: a new error
>>>
如何修复 getter/setter 以便对象再次拥有自己的错误字符串?
_err
是一个class变量,所有对象共享。由于 setter 方法就地修改了它,因此所有对象都可以看到更改。要解决此问题,请通过修改 MyHostBad
:
的构造函数使 _err
成为对象属性
def __init__(self, name=''):
'''Constructor'''
self.name = name
self._err = []
我有一个带有属性的 class。最初它包含一条错误消息的单个字符串。我想我会变得聪明并将它变成一个列表,所以每次我 'set' 属性时,它不会替换字符串,而是将字符串附加到列表中。
但是,现在 err
属性在对象之间共享,而不是每个对象都是唯一的。
这是我的代码(test.py
,在这个例子中被删减到最小值)
#!/usr/bin/python3
# pylint: disable=C0301
'''Testing MyHost class'''
class MyHostGood: # pylint: disable=R0903
'''Host class'''
err = ''
name = ''
def __init__(self, name=''):
'''Constructor'''
self.name = name
def __str__(self):
'''Return a printable user representation of the object - print(x)'''
info = f'{self.name}:'
# These are error/warning messages
if self.err:
info += f'\n└ ERROR: {self.err}'
return info
class MyHostBad: # pylint: disable=R0903
'''Host class'''
_err = []
name = ''
def __init__(self, name=''):
'''Constructor'''
self.name = name
def __str__(self):
'''Return a printable user representation of the object - print(x)'''
info = f'{self.name}:'
# These are error/warning messages
if self._err:
for errMsg in self._err:
info += f'\n└ ERROR: {errMsg}'
return info
@property
def err(self):
'''Return the list of error messages'''
return self._err
@err.setter
def err(self, arg):
'''Add another string to the error messages'''
if isinstance(arg, str):
self._err.append(arg)
if isinstance(arg, list):
self._err.extend(arg)
这里是好的 class,其中 err
属性是独一无二的:
>>> import test
>>> a = test.MyHostGood('foo')
>>> a.err = 'Here is one error string'
>>> print(a)
foo:
└ ERROR: Here is one error string
>>> b = test.MyHostGood('bar')
>>> print(b)
bar:
>>> b.err = 'a new error'
>>> print(a)
foo:
└ ERROR: Here is one error string
>>> print(b)
bar:
└ ERROR: a new error
>>>
这里 err
属性现在在对象之间共享:
>>> import test
>>> c = test.MyHostBad('wiz')
>>> c.err = 'Here is one error string'
>>> print(c)
wiz:
└ ERROR: Here is one error string
>>> d = test.MyHostBad('baz')
>>> print(d)
baz:
└ ERROR: Here is one error string
>>> d.err = 'a new error'
>>> print(c)
wiz:
└ ERROR: Here is one error string
└ ERROR: a new error
>>> print(d)
baz:
└ ERROR: Here is one error string
└ ERROR: a new error
>>>
如何修复 getter/setter 以便对象再次拥有自己的错误字符串?
_err
是一个class变量,所有对象共享。由于 setter 方法就地修改了它,因此所有对象都可以看到更改。要解决此问题,请通过修改 MyHostBad
:
_err
成为对象属性
def __init__(self, name=''):
'''Constructor'''
self.name = name
self._err = []