3

When defining class attributes through "calculated" names, as in:

class C(object):
    for name in (....):
        exec("%s = ..." % (name,...))

is there a different way of handling the numerous attribute definitions than by using an exec? getattr(C, name) does not work because C is not defined, during class construction...

Eric O. Lebigot
  • 91,433
  • 48
  • 218
  • 260
  • 1
    BTW: your tag of "compile-time" is jarring on a Python question. Compilation isn't really an important consideration here. This is about defining a class, not code compilation, which is an orthogonal issue. – Ned Batchelder May 26 '09 at 20:08
  • @Ned: You're right. I used the tag "compile-time" because the code in the example is only executed at compile time. Technically, it could be executed lazily, and the need for defining the class would still remain. – Eric O. Lebigot May 27 '09 at 14:59

4 Answers4

11

How about:

class C(object):
    blah blah

for name in (...):
    setattr(C, name, "....")

That is, do the attribute setting after the definition.

Ned Batchelder
  • 364,293
  • 75
  • 561
  • 662
3
class C (object):
    pass

c = C()
c.__dict__['foo'] = 42
c.foo # returns 42
Dan
  • 4,855
  • 3
  • 25
  • 21
2

If your entire class is "calculated", then may I suggest the type callable. This is especially useful if your original container was a dict:

d = dict(('member-%d' % k, k*100) for k in range(10))
C = type('C', (), d)

This would give you the same results as

class C(object):
    member-0 = 0
    member-1 = 100
    ...

If your needs are really complex, consider metaclasses. (In fact, type is a metaclass =)

Antti Rasinen
  • 9,918
  • 2
  • 22
  • 18
  • This results in attribute-names that cannot be accessed using normal Python syntax, because identifiers cannot contain the hyphen-minus character. It would be better to use `_` in this example. – gerrit Mar 21 '13 at 00:02
0

What about using metaclasses for this purpose?

Check out Question 100003 : What is a metaclass in Python?.

Community
  • 1
  • 1
Mike Hordecki
  • 92,113
  • 3
  • 26
  • 27