Reputation: 500
I'm working on a code dealing with dict data on python. While implementing such class, I have to define a lot of properties. It's not that hard, but recently I thought it would be much better if I could use something like helper function.
For example, let's assume that I have a class like the following.
class MyClass(object):
def __init__(self, data):
self.data = data
@property
def version(self):
return self.data["version"]
If I could write this class in something like the following.
class MyClass(object):
def __init__(self, data):
self.data = data
define_own_property("data", "version")
It looks trivial, but if I can do that, I think I can reuse a lot of validation/exception handling cases.
Any idea? :D
Upvotes: 2
Views: 133
Reputation: 251488
You can achieve something like that by just writing a function to return the accessor you want:
def define_own_property(attr, key):
def prop(self):
return getattr(self, attr)[key]
return property(prop)
class MyClass(object):
def __init__(self, data):
self.data = data
version = define_own_property("data", "version")
Note that you must do version = ...
There is no way to make a simple function call define_own_property
add a property to the class being defined, because that class doesn't yet exist so you can't reference it.
Another possibility is to give your class an attribute that is a list or dict or something containing the relevant parameters ("data", "version", etc.), then write a class decorator that reads these parameters and auto-creates the series of properties. This would remove the need to define the properties inside the class at all; you would just give a list of the things you wanted the properties to access, and use the decorator once on the class.
Upvotes: 3
Reputation: 310089
It seems like you could use a descriptor:
class Descr(object):
def __init__(self,attr,key):
self.attr = attr
self.key = key
def __get__(self,obj,type=None):
return getattr(obj,self.attr)[self.key]
def __set__(self,obj,value):
getattr(obj,self.attr)[self.key] = value
def __delete__(self,obj):
del getattr(obj,self.attr)[self.key]
class MyClass(object):
def __init__(self, data):
self.data = data
version = Descr("data","version")
foobar = Descr("data","foobar")
a = MyClass({})
a.version = 1
print a.version
a.foobar = 'string'
print a.data
Upvotes: 2