python - 是否有一种紧凑的方法可以在 python 类中声明几个类似的属性?
问题描述
我正在一个更大的python模块中工作,其中可以保存包含类dict类实例程序集的“项目”,但是为了保存类的属性,它们必须存储在类中的特定字典中。通过将属性写为属性,我可以将属性作为简单属性(self.x
而不是self.properties['x']
)进行访问。但是我最多有 9 个这样的东西,给它们每个都一个 getter、setter 和 deleter 似乎是在浪费空间,尤其是因为它们都那么微不足道。有没有更好的办法?
太长:
class MyClass(dict):
@property
def variable1(self):
return self.properties.get('variable1', None)
@variable1.setter
def variable1(self, value):
self.properties['variable1'] = value
@variable1.deleter
def variable1(self):
self.properties['variable1'] = None
# ... same for variables 2 - 8, so boring
@property
def variable9(self):
return self.properties.get('variable9', None)
@variable9.setter
def variable9(self, value):
self.properties['variable9'] = value
@variable9.deleter
def variable9(self):
self.properties['variable9'] = None
def __init__(self, variable1='default1', variable9='default9'):
self.properties = dict(variable1=variable1, variable9=variable9)
dict.__init__(self)
我怎样才能循环属性声明,这样会更短?
奖励:如果我做一个循环,有没有办法在需要时对某些变量进行小幅定制(也许将要列出的东西声明为字典中的键,其中值是小定制的说明)?
上面例子的测试/使用:
from var_test import MyClass # If you saved it in var_test.py
a = MyClass(variable1=1234)
b = MyClass(variable1='wheee')
assert a.variable1 is not b.variable1
assert a.properties['variable1'] == a.variable1
assert a.variable1 == 1234
解决方案
是的,您可以动态创建属性对象,并将它们添加到类中:
def gen_property(name):
def getter(self):
return self.properties.get(name, None)
def setter(self, value):
self.properties[name] = value
def deleter(self):
self.properties[name] = None
return property(getter, setter, deleter)
class MyClass(dict):
def __init__(self, variable1='default1', variable9='default9'):
self.properties = dict(variable1=variable1, variable9=variable9)
dict.__init__(self)
for number in range(1, 10):
name = 'variable{}'.format(number)
setattr(MyClass, name, gen_property(name))
但是,使用属性访问自定义钩子并将属性名称代理到self.properties
那里的字典可能要干净得多:
class MyClass(dict):
def __init__(self, variable1='default1', variable9='default9'):
self.properties = dict(variable1=variable1, variable9=variable9)
dict.__init__(self)
def __getattr__(self, name):
if name.startswith('variable') and name[8:].isdigit():
return self.properties.get(name, None)
raise AttributeError(name)
def __setattr__(self, name, value):
if name.startswith('variable') and name[8:].isdigit():
self.properties[name] = value
return
super().__setattr__(name, value)
def __delattr__(self, name):
if name.startswith('variable') and name[8:].isdigit():
self.properties[name] = None
return
super().__delattr__(name)
推荐阅读
- reactjs - 如何在 JSX 中使用 amp-state?
- python - python的aubio库中缓冲区大小和跃点大小的作用是什么?
- python - Python中基于多列垂直展平多列并合并
- powershell - 如何使用powershell检查重复的多个文件?
- django - 如何在 django 中创建 2 级管理员用户,每个用户将只管理他创建的用户?
- if-statement - Vlookup 然后在 Google 表格中返回不同的行
- c++ - 由于某种原因,我的代码中出现了 [json.exception.type_error.302] 。我知道错误是什么意思,但我不知道哪里有问题
- php - 为什么在 YII2 活动表单中没有定义 $model 变量时出现错误
- matlab - MATLAB:x 轴上绘制的是什么?
- android - 如何从传感器 TYPE_ROTATION_VECTOR 获得的 3D 矩阵计算 2D 旋转(锁定一个轴旋转)