In python, is there a way to get the class name in the "static constructor"? I would like to initialize a class variable using an inherited class method.
class A():
#classmethod
def _getInit(cls):
return 'Hello ' + cls.__name__
class B(A):
staticField = B._getInit()
NameError: name 'B' is not defined
The name B is not assigned to until the full class suite has been executed and a class object has been created. For the same reason, the __name__ attribute on the class is not set until the class object is created either.
You'd have to assign that attribute afterwards:
class A():
#classmethod
def _getInit(cls):
return 'Hello ' + cls.__name__
class B(A):
pass
B.staticField = B._getInit()
The alternative is to use a class decorator (which is passed the newly-created class object) or use a metaclass (which creates the class object in the first place and is given the name to use).
Related
For example:
class abc:
def show(self):
print(self)
print(a)
a = abc()
a.show()
Here a is an instance of the class, which can be directly referred to in the method by its name, in addition to by the first argument self.
Why is this allowed?
I'm trying to do the following:
class A:
#classmethod
def test_function(cls, message):
cls.__get_the_function()
class B(A):
#classmethod
def __get_the_function(cls):
return print("BBBB")
class C(A):
#classmethod
def __get_the_function(cls):
return print("CCCC")
however when I call:
B.test_function("Test")
I get the following:
AttributeError: type object 'B' has no attribute '_A__get_the_function'
I want class A to __get_the_function from the subclass (either class B or C depends on which one I use), but it looks like it is trying to look for it in itself.
NOTE: I'm using Python 3.8.2
__-prefixed names are handled specially during class creation. The name is replaced when the function is defined by a mangled name, as if you had defined the function as
#classmethod
def test_function(cls, message):
cls._A__get_the_function()
in the first place.
This is done to explicitly provide a way to hide a name from a subclass. Since you want to override the name, __get_the_function isn't an appropriate name; use an ordinary _-prefixed name if you want to mark it as private:
class A:
#classmethod
def test_function(cls, message):
cls._get_the_function()
# Define *something*, since test_function assumes it
# will exist. It doesn't have to *do* anything, though,
# until you override it.
#classmethod
def _get_the_function(cls):
pass
Is there a way to get the name of a class at class level in Python?
Minimum working example:
class TestClass:
print("We are now in the class {} at class level".format(WHAT SHOULD I PUT HERE?)) # Should return "We are now in the class TestClass at class level"
pass
Here's how you can find out:
class TestClass:
print(locals())
This prints:
{'__module__': '__main__', '__qualname__': 'TestClass'}
So you can use __qualname__, i.e.
class TestClass:
print("We are now in the class {} at class level".format(__qualname__))
This works :
class Test :
CLASSNAME = locals()['__qualname__']
Use the CLASSNAME variable anywhere in the class or outside.
For defined classes only: Use type(self).__name__ where .__name__ is a default attribute.
Refer to #Alex Hall's answer for using the class name before __init__ takes place, using locals().
I want to call an instance method but the instance itself is unknown to me. The instance can be identified by it's attributes which I know, e.g. a unique name.
Here're my class definitions and instantiation:
from abc import ABCMeta
class MyAbstractClass():
__metaclass__ = ABCMeta
def do_something(self):
print(self.name)
class MyFirstClass(MyAbstractClass):
def __init__(self):
self.name = 'first'
class MySecondClass(MyAbstractClass):
def __init__(self):
self.name = 'second'
my_first_class_instance = MyFirstClass()
my_second_class_instance = MySecondClass()
What I want to achive is a look-up by name:
def myPrint('first'):
# should call my_first_class_instance.do_something()
def myPrint('second'):
# should call my_second_class_instance.do_something()
I looked into the built-in class methods but didn't find a way to manage the parametrization of the calls.
What's a good way of doing this?
class A(object):
class B(object): pass
class C(A.B): pass
results in
NameError: name 'A' is not defined
How do I inherit from B in C, if they are adjacent , both nested in A (inner classes)?
You cannot use A until the class body has finished executing.
You can refer to 'local' names; the class body is executed as a function, and the local namespace of that function is used to supply the class attributes; within the class body, B is a local name:
class A(object):
class B(object): pass
class C(B): pass