ko_*_*_00 0 python oop dictionary python-descriptors
main():请参阅注释中提到的结果的函数。*一般注意事项:当Class()有一个attribute包含例如str->时,@propery.setter一旦设置就会验证。
但是,当我将 a 存储dictionary在 中时Class.attribute,@property.setter如果我直接设置 a ,则 My 不起作用key : value
class CoinJar():
def __init__(self):
self._priceDict = {'current' : 0.0, 'high' : 0.0, 'low' : 0.0}
self.klines = {}
self.volume = {}
def __str__(self):
return f'\n\U0001F36A'
@property
def priceDict(self):
return self._priceDict
@priceDict.setter
def priceDict(self, priceDict):
print('setting price')
try:
newPrice = float(priceDict.get('current'))
except ValueError as e:
print(f'Input cannot be converted to float {e}')
# Exceptions
if len(priceDict.keys()) == 0 or newPrice == None or type(newPrice) not in [int, float]:
raise ValueError('setting illegal value')
#setting high, low, current
self._priceDict['current'] = newPrice
if newPrice > self._priceDict['high']:
self._priceDict['high'] = newPrice
if newPrice < self._priceDict['low'] or self._priceDict['low'] == 0.0:
self._priceDict['low'] = newPrice
def main():
btc = CoinJar()
btc.priceDict = {'current' : 500} # This is calling priceDict.setter => accepts and performs the .setter expressions
btc.priceDict['flamingo'] = 20 # This is not calling priceDict.setter => can do what i want, with 'current, high, flamingo, *'
btc.priceDict = {'flamingo' : 500} # This is calling priceDict.setter => raises Exception (as expected)
print(btc)
def retrieveData():
...
def analyseData():
...
if __name__ == '__main__':
main()
Run Code Online (Sandbox Code Playgroud)
看看这个简化的例子:
class AClass:
def __init__(self):
self._some_dict = None
@property
def some_dict(self):
print('getting')
return self._some_dict
@some_dict.setter
def some_dict(self, value):
print('setting')
self._some_dict = value
an_obj = AClass()
an_obj.some_dict = {} # setter gets called
an_obj.some_dict['a_key'] = 1 # getter gets called, as dict is being accessed
Run Code Online (Sandbox Code Playgroud)
当需要设置属性本身的值时,将调用属性的属性设置器。即当您为属性分配新字典时dict。
当访问属性(“读取”/“获取”)时,将调用属性 getter。
当您以其他方式操作属性(例如为字典设置键或值)时,不会调用 setter。你可以触发它,但你必须覆盖字典。
像这样的东西:
class MyDict(dict):
def __setitem__(self, key, *args, **kwargs):
print('setting a dictionary value')
super().__setitem__(key, *args, **kwargs)
class AClass:
def __init__(self):
self._some_dict = None
@property
def some_dict(self):
print('getting')
return self._some_dict
@some_dict.setter
def some_dict(self, value):
print('setting')
self._some_dict = MyDict(value)
an_obj = AClass()
an_obj.some_dict = {} # setter gets called
an_obj.some_dict['a_key'] = 1 # getter gets called, as well as item setter
# Note: this just calls setter, as it just directly sets the attribute to the new dict:
an_obj.some_dict = {'a_key': 1}
Run Code Online (Sandbox Code Playgroud)
另一件需要注意的事情是,上面的代码不会自动递归地工作。也就是说,如果您的字典包含更多字典,它们不会自动转换为MyDict,因此会发生这种情况:
an_obj = AClass()
an_obj.some_dict = {} # setter
an_obj.some_dict['a_key'] = {} # getter and item setter
an_obj.some_dict['a_key']['another_key'] = 1 # only getter
Run Code Online (Sandbox Code Playgroud)
MyDict您可以通过将任何dict值转换为 a 来继续添加功能MyDict,但还有其他问题需要考虑 - 根据需要进行调整:
class MyDict(dict):
def __setitem__(self, key, value, *args, **kwargs):
print('setting a dictionary value')
if isinstance(value, dict) and not isinstance(value, MyDict):
value = MyDict(value)
super().__setitem__(key, value, *args, **kwargs)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
573 次 |
| 最近记录: |