当前位置:  开发笔记 > 编程语言 > 正文

如何使用动态名称实现property()(在python中)

如何解决《如何使用动态名称实现property()(在python中)》经验,为你挑选了3个好方法。

我正在为单个神经元编程模拟.因此我必须处理很多参数.现在的想法是我有两个类,一个用于SingleParameter,一个用于参数集合.我使用property()来轻松访问参数值并使代码更具可读性.这适用于sinlge参数,但我不知道如何为集合实现它,因为我想在SingleParameter之后命名Collection中的属性.这是一个例子:

class SingleParameter(object):
  def __init__(self, name, default_value=0, unit='not specified'):
    self.name = name
    self.default_value = default_value
    self.unit = unit
    self.set(default_value)
  def get(self):
    return self._v
  def set(self, value):
    self._v = value
  v = property(fget=get, fset=set, doc='value of parameter')

par1 = SingleParameter(name='par1', default_value=10, unit='mV')
par2 = SingleParameter(name='par2', default_value=20, unit='mA')

# par1 and par2 I can access perfectly via 'p1.v = ...'
# or get its value with 'p1.v'

class Collection(object):
  def __init__(self):
    self.dict = {}
  def __getitem__(self, name):
    return self.dict[name] # get the whole object
    # to get the value instead:
    # return self.dict[name].v
  def add(self, parameter):
    self.dict[parameter.name] = parameter
    # now comes the part that I don't know how to implement with property():
    # It shoule be something like
    # self.__dict__[parameter.name] = property(...) ?

col = Collection()
col.add(par1)
col.add(par2)
col['par1'] # gives the whole object

# Now here is what I would like to get:
# col.par1 -> should result like col['par1'].v
# col.par1 = 5 -> should result like col['par1'].v = 5

我理解property()的其他问题:

为什么托管属性只适用于类属性而不适用于python中的实例属性?

如何在python中通过__dict__分配新的类属性?

S.Lott.. 10

看看内置函数getattrsetattr.你可能会更开心.



1> S.Lott..:

看看内置函数getattrsetattr.你可能会更开心.



2> meteore..:

对两个类使用相同的get/set函数会强制您使用参数列表进行丑陋的黑客攻击.非常粗略,我就是这样做的:

在类SingleParameter中,像往常一样定义get和set:

def get(self):
  return self._s
def set(self, value):
  self._s = value

在类Collection中,在创建属性之前无法知道信息,因此您需要定义metaset/metaget函数,并稍后使用lambda函数对它们进行详细说明:

def metaget(self, par):
  return par.s
def metaset(self, value, par):
  par.s = value
def add(self, par):
  self[par.name] = par
  setattr(Collection, par.name,
    property(
      fget=lambda x : Collection.metaget(x, par),
      fset=lambda x, y : Collection.metaset(x,y, par))



3> Abgan..:

属性用于动态评估属性或使其成为只读属性.您需要的是自定义属性访问.__getattr____setattr__做到这一点真的很细,还有还有__getattribute__,如果__getattr__是不够的.

有关详细信息,请参阅有关自定义属性访问的Python文档.

推荐阅读
依然-狠幸福
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有