Setting a class attribute with a given name in python while defining the class
Solution 1
You'll need to use a metaclass for this:
property = 'foo'
value = 'bar'
class MC(type):
def __init__(cls, name, bases, dict):
setattr(cls, property, value)
super(MC, cls).__init__(name, bases, dict)
class C(object):
__metaclass__ = MC
print C.foo
Solution 2
You can do it even simpler:
class A():
vars()['key'] = 'value'
In contrast to the previous answer, this solution plays well with external metaclasses (for ex., Django models).
Solution 3
This may be because the class A
is not fully initialized when you do your setattr(A, p, v)
there.
The first thing to try would be to just move the settattr down to after you close the class
block and see if that works, e.g.
class A(object):
pass
setattr(A, property, value)
Otherwise, that thing Ignacio just said about metaclasses.
Solution 4
So I know this is really old and probably beating a dead horse and this may not have been possible at the time but I cam across this trying to solve my own problem.
I realized this can be accomplished without metaclassing.
The setattr takes and object, accessor name, and value. Well the object is not the class name it's the specific instance of the class, which can be accomplished with self.
class A(object):
def __init__(self):
self.a = 'i am a accessor'
setattr(self, 'key', 'value')
a = A()
print a.a
print a.key
prismofeverything
Updated on June 07, 2022Comments
-
prismofeverything about 2 years
I am trying to do something like this:
property = 'name' value = Thing() class A: setattr(A, property, value) other_thing = 'normal attribute' def __init__(self, etc) #etc..........
But I can't seem to find the reference to the class to get the
setattr
to work the same as just assigning a variable in the class definition. How can I do this? -
Mike Graham over 14 yearsThis solution works very well. There is no need to do this in a metaclass when you can do it directly.
-
TomSawyer over 6 yearsHow do i pass parameter to the file like this
a = MC(params)
( mc.py is a particular file),__metaclass__ = MC(params)
doesn't work? -
Ignacio Vazquez-Abrams over 6 yearsUnless
MC
is a callable that returns a metaclass, you don't. And the metaclass will only be set the first time the class is defined so this isn't a way of setting a dynamic metaclass. -
martineau about 6 yearsYour code is setting an instance attribute, which isn't the same as defining a class attribute—since
self
is an instance of classA
not the class itself. In other words, it doesn't answer the question being asked. -
martineau about 6 yearsAnother advantage is that it avoids the issues caused by the change in the syntax for specifying metaclasses between Python 2 and 3—so it's a more version independent approach. If you think about it, it effectively gives a
self
(orcls
) argument to the code within a class definition. -
martineau about 6 years@TomSawyer: There are at least a couple of ways I know of to pass arguments to a metaclass. Suggest you search here for questions and answers about the subject.
-
martineau almost 6 yearsAlthough it might seem (very slightly) more complicated, as @Vitalik Verhovodov shows in his answer, you can use
vars()
within the class body itself to get access to the class being defined's__dict__
. One you have that, you're pretty much free to modify its contents easily. -
Eric Smith almost 5 yearsThis is excellent! I've often wanted to use setattr() on a class under construction, e.g., when doing table-driven construction of a bunch of similar properties. Before I either had to use a metaclass, or define a class method that I call right after the close of the class definition proper. I didn't know about vars().
-
zhy about 3 yearsuse
class C(object, metaclass=MC): pass
in python3