3

Using Python I want to create a property in a class, but having the name of it in a string. Normally you do:

blah = property(get_blah, set_blah, del_blah, "bleh blih")

where get_, set_ and del_blah have been defined accordingly. I've tried to do the same with the name of the property in a variable, like this:

setattr(self, "blah", property(self.get_blah, self.set_blah, self.del_blah, "bleh blih"))

But that doesn't work. The first case blah returns the value of the property, on the second case, it returns a property, that is <property object at 0xbb1aa0>. How should I define it so it works?

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
Pablo Fernandez
  • 279,434
  • 135
  • 377
  • 622
  • Usually, we define the property with a fixed, obvious, invariant name. We then use getattr to reference the properties flexibly. What are you trying to accomplish with this? What's the bigger picture? There's probably a simpler way; please provide background so we can suggest something that will actually work. – S.Lott Jul 31 '09 at 13:20
  • I'm making a class to hold the configuration of a process and it will have a ton of properties all very similar in how they are set, get, validated, documented, and so on. I'm trying to remove code duplication. – Pablo Fernandez Jul 31 '09 at 13:23
  • @J. Pablo Fernández: Please update your question. The comments are not the place to put important information. It sounds like you're simply talking about a class that wraps a dictionary of property values. But you need to provide some details on your use case. More than you can cram into a comment. It's your question; update it, please. – S.Lott Jul 31 '09 at 13:51

3 Answers3

2

As much I would say, the difference is, that in the first version, you change the classes attribute blah to the result of property and in the second you set it at the instance (which is different!).

How about this version:

setattr(MyClass, "blah", property(self.get_blah, self.set_blah,
        self.del_blah, "bleh blih"))

you can also do this:

setattr(type(self), "blah", property(self.get_blah, self.set_blah,
        self.del_blah, "bleh blih"))
Pablo Fernandez
  • 279,434
  • 135
  • 377
  • 622
Juergen
  • 12,378
  • 7
  • 39
  • 55
1

One way is to write into locals():

class X:
    for attr in ["a","b","c"]:
        def getter(self, name=attr):
            return name+"_value"
        locals()[attr] = property(getter, None, None, attr)

x = X()
print x.a
print x.b
print x.c

gives

a_value
b_value
c_value
Martin v. Löwis
  • 124,830
  • 17
  • 198
  • 235
1

If I understand what you're trying to do, you could accomplish it by overriding the class's getattr and setattr methods.

For example:

class Something(object):
    def __getattr__(self, name):
        # The name of the property retrieved is a string called name
        return "You're getting %s" % name

something = Something()

print something.foo
print something.bar

Will print:

You're getting foo
You're getting bar

This way you can have a generic getter and setter that has the name of the property in a string and does something with it accordingly.

Andre Miller
  • 15,255
  • 6
  • 55
  • 53