Question

I have a python class (actually its a Google App Engine model) which looks like this:

class MyClass(ParentClass):
    variable_one = PropertyClass(...)
    variable_two = PropertyClass(...)

I intend to build a system which can describe the difference between two instances of this class that represent two versions of the entity at different points in time. Ultimately it would produce a string like

"Variable One changed from 'foo' to 'bar', Variable Two changed from empty to 'baz'"

So, I need to somewhere to store the fact that "variable_one" should be displayed as "Variable One" and so on. Coming from a C# background, my instinct is to use Attributes, for example:

class MyClass : ParentClass
{
    [DisplayName("Variable One")]
    public PropertyClass variable_one;

    [DisplayName("Variable Two")]
    public PropertyClass variable_two;
}

At first, the python equivalent appears to be decorators:

class MyClass(ParentClass):
    @display_name("Variable One")
    variable_one = PropertyClass(...)

    @display_name("Variable Two")
    variable_two = PropertyClass(...)

However, decorators are really doing function currying and as the class variable definition is just assigning an instance of the PropertyClass to variable_one and variable_two it doesn't look like that would be valid python. In any case, I'm not sure how I'd write that.

One option appears to be to extend the PropertyClass...

class MyClass(ParentClass):
    variable_one = MyPropertyClass("Variable One", ...)
    variable_two = MyPropertyClass("Variable Two", ...)

But there are a few different property classes being used and I want to add one common behaviour to all of them so this seems like too much effort.

I guess I could define a dictionary:

class MyClass(ParentClass):
    variable_one = PropertyClass(...)
    variable_two = PropertyClass(...)
    variable_display_names = {
        "variable_one": "Variable One",
        "variable_two": "Variable Two"
    }

But I'm hoping to hear from some more experienced pythoners about the best most pythonic way of achieving this.

Was it helpful?

Solution

The datastore Property classes are descriptors (like the python @property decorator), but as custom classes that do not implement __setattr__ you can set arbitrary attributes on those objects:

 class MyClass(ParentClass):
     variable_one = PropertyClass(...)
     variable_one.display_name = "Variable One"

     variable_two = PropertyClass(...)
     variable_two.display_name = "Variable Two"

which can be generalized to a decorator with:

def display_name(dispname):
    def decorate_with_display_name(prop):
        prop.display_name = dispname
        return prop
    return decorate_with_display_name

As long as you access the Property via the class (and not the instance) you can retrieve those values again; given an instance you can do print type(instance).variable_two.display_name, for example.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top