I’m new to Python so forgive me if I’m not even using the right terminology… I’m using Python 3.2 and I’m trying to figure out whether I can decorate a class property with some declarative-style information.
In my mind it would look like this:
class MyTestClass:
def __init__(self, foo):
self.foo = foo
@property
@somedeclarativeInfo("ABC",123)
def radius(self):
return self.__foo
@radius.setter
def radius(self, foo):
self.__foo = foo
There are then two different things I’d want to do with the class:
A – Be able to interact with the foo property just like any other property (simple gets and sets)
B – Be able to dynamically find properties on a particular class that are decorated with this descriptor and be able to pull out the “ABC” and 123 values, etc.
I think maybe I should be creating a descriptor to accomplish what I want, but I’m not sure if I’m on the right track, or if this can be done.
Since my background is .Net I whipped up the following example to show what I want to do, in case that helps anyone understand my goal:
using System;
using System.Reflection;
namespace SampleWithProperties
{
public class MyCustomAttribute : Attribute
{
public string Val1;
public string Val2;
public MyCustomAttribute(string val1,string val2)
{
Val2 = val2;
Val1 = val1;
}
}
public class Foo
{
[MyCustomAttribute("abc","def")]
public string PropertyA { get; set; }
[MyCustomAttribute("xyz","X")]
public int PropertyB { get; set; }
public string PropertyC { get; set; }
}
class Program
{
static void Main(string[] args)
{
// Show that we can figure out which properties have the custom attribute,
// and that we can get the values for Val1 and Val2
foreach(PropertyInfo propertyInfo in typeof(Foo).GetProperties())
{
Console.WriteLine("Found a property named "+propertyInfo.Name);
foreach(Attribute attribute in propertyInfo.GetCustomAttributes(
attributeType:typeof(MyCustomAttribute),inherit:true))
{
Console.WriteLine("Found a MyCustomAttribute on the property.");
MyCustomAttribute myCustomAttribute = attribute as MyCustomAttribute;
Console.WriteLine("Val1 = " + myCustomAttribute.Val1);
Console.WriteLine("Val2 = " + myCustomAttribute.Val2);
}
Console.WriteLine();
}
// Show that the properties can be used like normal
Foo foo = new Foo {PropertyA = "X", PropertyB = 2, PropertyC = "Z"};
Console.WriteLine("Created an instance of Foo just for fun. Its property values are "+
foo.PropertyA+","+foo.PropertyB+","+foo.PropertyC);
}
}
}
Can this be done?
OK, I wrote this question when I was first getting started with Python. I now know how to do in Python exactly what the .Net sample code I posted did. Granted, the biggest thing I didn’t realize when I originally posted the question was that descriptors alter the behavior of your attributes/properties(whatever you call them). Nonetheless, we can still allow these attributes to act like properties (and not change their behavior) yet put some metadata on them with the decorator. I’m currently implementing some protocol serialization/deserialization stuff where this is going to come in handy.
The output is: