How To Define Properties In __init__
Solution 1:
You need to set the properties on the class (ie: self.__class__
), not on the object (ie: self
). For example:
classBasket(object):
def__init__(self):
# add all the propertiessetattr(self.__class__, 'Apple', property(lambda s : 'Apple') )
setattr(self.__class__, 'Pear', property(lambda s : 'Pear') )
# normal property
Air = property(lambda s : "Air")
if __name__ == "__main__":
b = Basket()
print b.Air # outputs: "Air"print b.Apple # outputs: "Apple"print b.Pear # outputs: "Pear"
For what it's worth, your usage of p
when creating lamdas in the loop, doesn't give the behavior that you would expect. Since the value of p
is changed while going through the loop, the two properties set in the loop both return the same value: the last value of p
.
Solution 2:
This does what you wanted:
classBasket(object):
def__init__(self):
# add all the propertiesdefmake_prop( name ):
defgetter( self ):
return"I'm a " + name
returnproperty(getter)
for p in self.PropNames():
setattr(Basket, p, make_prop(p) )
defPropNames(self):
# The names of all the propertiesreturn ['Apple', 'Pear', 'Bread']
# normal property
Air = property(lambda s : "I'm Air")
if __name__ == "__main__":
b = Basket()
print b.Air
print b.Apple
print b.Pear
Another way to do it would be a metaclass ... but they confuse a lot of people ^^.
Because I'm bored:
classWithProperties(type):
""" Converts `__props__` names to actual properties """def__new__(cls, name, bases, attrs):
props = set( attrs.get('__props__', () ) )
for base in bases:
props |= set( getattr( base, '__props__', () ) )
defmake_prop( name ):
defgetter( self ):
return"I'm a " + name
returnproperty( getter )
for prop in props:
attrs[ prop ] = make_prop( prop )
returnsuper(WithProperties, cls).__new__(cls, name, bases, attrs)
classBasket(object):
__metaclass__ = WithProperties
__props__ = ['Apple', 'Pear']
Air = property(lambda s : "I'm Air")
classOtherBasket(Basket):
__props__ = ['Fish', 'Bread']
if __name__ == "__main__":
b = Basket()
print b.Air
print b.Apple
print b.Pear
c = OtherBasket()
print c.Air
print c.Apple
print c.Pear
print c.Fish
print c.Bread
Solution 3:
Why are you defining properties at __init__
time? It's confusing and clever, so you better have a really good reason. The loop problem that Stef pointed out is just one example of why this should be avoided.
If you need to redifine which properties a subclass has, you can just do del self.<property name>
in the subclass __init__
method, or define new properties in the subclass.
Also, some style nitpicks:
- Indent to 4 spaces, not 2
- Don't mix quote types unnecessarily
- Use underscores instead of camel case for method names.
PropNames
->prop_names
PropNames
doesn't really need to be a method
Post a Comment for "How To Define Properties In __init__"