How to implement property() with dynamic name (in

2019-04-05 23:15发布

I am programming a simulations for single neurons. Therefore I have to handle a lot of Parameters. Now the Idea is that I have two classes, one for a SingleParameter and a Collection of parameters. I use property() to access the parameter value easy and to make the code more readable. This works perfect for a sinlge parameter but I don't know how to implement it for the collection as I want to name the property in Collection after the SingleParameter. Here an example:

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

Other questions that I put to understand property():

7条回答
对你真心纯属浪费
2楼-- · 2019-04-05 23:53

Finally I succeded to implement the classes with property(). Thanks a lot for the advice. It took me quite a bit to work it out - but I can promise you that this exercise helps you to understand better pythons OOP.

I implemented it also with __getattr__ and __setattr__ but still don't know the advantages and disadvantages to the property-solution. But this seems to be worth another question. The property-solutions seems to be quit clean.

So here is the code:

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(*args):
    self = args[0]
    print "get(): "
    print args
    return self._v
  def set(*args):
    print "set(): "
    print args
    self = args[0]
    value = args[-1]
    self._v = value
  v = property(fget=get, fset=set, doc='value of parameter')

class Collection(dict):
  # inheriting from dict saves the methods: __getitem__ and __init__
  def add(self, par):
    self[par.name] = par
    # Now here comes the tricky part.
    # (Note: this property call the get() and set() methods with one
    # more argument than the property of SingleParameter)
    setattr(Collection, par.name,
      property(fget=par.get, fset=par.set))

# Applying the classes:
par1 = SingleParameter(name='par1', default_value=10, unit='mV')
par2 = SingleParameter(name='par2', default_value=20, unit='mA')
col = Collection()
col.add(par1)
col.add(par2)
# Setting parameter values:
par1.v = 13
col.par1 = 14
# Getting parameter values:
par1.v
col.par1
# checking identity:
par1.v is col.par1
# to access the whole object:
col['par1']

As I am new I am not sure how to move on: how to treat follow up questions (like this itself):

  • get() is seems to be called twice - why?
  • oop-design: property vs. "__getattr__ & __setattr__" - when should I use what?
  • is it rude to check the own answer to the own question as accepted?
  • is it recommended to rename the title in order to put correlated questions or questions elaborated with the same example into the same context?

Other questions that I put to understand property():

查看更多
登录 后发表回答