Reputation: 1812
I'm trying to have a default instance of a class. I want to have
class Foo():
def __init__(self):
....
_default = Foo()
@staticmethod
def get_default():
return _default
However _default = Foo()
leads to NameError: name 'Foo' is not defined
Upvotes: 0
Views: 355
Reputation: 184455
Foo
does not exist until the class definition is finalized. You can easily refer to it after the class definition, though:
class Foo(object):
def __init__(self):
# ....
Foo.default_instance = Foo()
Note also that I have removed the superfluous getter method in favor of a plain old attribute.
You can also solve the problem with a decorator:
def defaultinstance(Class):
Class.default_instance = Class()
return Class
@defaultinstance
class Foo(object):
# ...
Or, gratuitously, with a metaclass:
def defaultmeta(name, bases, attrs):
Class = type(name, bases, attrs)
Class.default_instance = Class()
return Class
# Python 2.x usage
class Foo(object):
__metaclass__ = defaultmeta
# ...
# Python 3.x usage
class Foo(metaclass=defaultmeta):
# ...
When might you might want to use each method?
Upvotes: 5
Reputation: 15817
You may lazily initialize your default instance.
class Foo(object):
_default = None
@staticmethod
def get_default():
if not Foo._default:
Foo._default = Foo()
return Foo._default
Upvotes: 0
Reputation: 1125048
You cannot refer to a class that doesn't yet exist. Within the class definition body, the Foo
class is not yet created.
Add the attribute after the class has been created:
class Foo():
def __init__(self):
....
@staticmethod
def get_default():
return Foo._default
Foo._default = Foo()
Note that you also need to alter the get_default()
static method; the class body doesn't form a scope, so you cannot reach _default
as a non-local from get_default()
.
You are now, however, repeating yourself a lot. Reduce repetition a little by making get_default()
a classmethod instead:
class Foo():
def __init__(self):
....
@classmethod
def get_default(cls):
return cls._default
Foo._default = Foo()
or create the default on first call:
class Foo():
def __init__(self):
....
@classmethod
def get_default(cls):
if not hasattr(cls, '_default'):
cls._default = cls()
return cls._default
Upvotes: 2