Reputation: 287400
I wanted to do something like setattr to a class in class method in Python, but the class doesn't exist so I basically get:
NameError: global name 'ClassName' is not defined
Is there a way for a class method to modify the class? Something like this but that actually works:
class ClassName(object):
def HocusPocus(name):
setattr(ClassName, name, name)
HocusPocus("blah")
HocusPocus("bleh")
Upvotes: 0
Views: 690
Reputation: 881575
While many good suggestions have been advanced, the closest one can get to the originally requested code, that is:
class ClassName(object):
def HocusPocus(name):
setattr(ClassName, name, property(fget=..., fset=...))
HocusPocus("blah")
HocusPocus("bleh")
is this:
class ClassName(object):
def HocusPocus(name):
return property(fget=..., fset=...)
blah = HocusPocus("blah")
bleh = HocusPocus("bleh")
I'm assuming the mysterious ...
redacted parts need access to name
too (otherwise it's not necessary to pass it as an argument).
The point is that, within the class body, HocusPocus is still just a function (since the class object doesn't exist yet until the class body finishes executing, the body is essentially like a function body that's running in its local dict [without the namespace optimizations typically performed by the Python compiler on locals of a real function, but that only makes the semantics simpler!]) and in particular it can be called within that body, can return a value, that value can be assigned (to a local variable of the class body, which will become a class attribute at the end of the body's execution), etc.
If you don't want ClassName.HocusPocus hanging around later, when you're done executing it within the class body just add a del
statement (e.g. as the last statement in the class body):
del HocusPocus
Upvotes: 0
Reputation: 50898
Class methods get the class passed as the first argument:
class Bla(object):
@classmethod
def cm(cls,value):
cls.storedValue = value
Bla.cm("Hello")
print Bla.storedValue # prints "Hello"
Edit: I think I understand your problem now. If I get it correctly, all you want to do is this:
class Bla(object):
storedValue = "Hello again"
print Bla.storedValue # prints "Hello again"
Class creation in Python (pretty much) simply means:
Since storedValue
is in the namespace after step 2, it's turned into a class attribute in step 3.
Upvotes: 5
Reputation: 81278
Another way you could do this would be to use a class decorator, though these are only available from Python 2.6 onwards IIRC.
Something like this:
def addattributes(cls):
cls.foobar = 10
return cls
@addattributes
class MyClass(object):
pass
print MyClass.foobar
This kind of this most useful when you want to "decorate" a number of classes with some specific functionality / properties. In your case, if you only want to do this once, you might just want to use class methods as previously shown.
Upvotes: 0