redism
redism

Reputation: 500

python - setting property of class on module loading

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

Answers (2)

BrenBarn
BrenBarn

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

mgilson
mgilson

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

Related Questions