Я хотел бы создать метод класса или абстрактный метод в родительском классе. Этот метод должен возвращать имя класса реализации.
Например, используя метод класса:
class TestParentClass():
somefield = ""
# create a method to get the name of this class.
@classmethod
def get_name(cls):
class_name = cls.__name__
return class_name
class TestClass(TestParentClass):
somefield = TestParentClass.get_name()
print(TestClass().somefield) # I want this to print 'TestClass'
Я бы хотел, чтобы оператор печати печатал TestClass
, но это будет печататься TestParentClass
.
Я также попробовал использовать абстрактный метод, например:
class TestParentClass():
somefield = ""
# create a method to get the name of this class.
@abstractmethod
def get_name():
class_name = __class__.__name__
print(class_name)
return class_name
Однако и это будет напечатано TestParentClass
.
Использование конструктора в дочернем классе также не делает ничего другого, т.е.:
class TestClass(TestParentClass):
def __init__(self) -> None:
somefield = TestParentClass.get_name() # still sets 'TestParentClass'
Есть ли способ сделать это в Python?
Другими словами, мне бы хотелось чего-то эквивалентного этому решению С#:
class TestParentClass
{
public string SomeField { get; set; }
public string GetName()
{
return this.GetType().Name;
}
}
class TestClass : TestParentClass
{
public TestClass()
{
SomeField = this.GetName();
}
}
void Main()
{
Console.WriteLine(new TestClass().SomeField); // This prints TestClass.
}
🤔 А знаете ли вы, что...
Синтаксис Python известен своей простотой и читаемостью.
Как указано в комментариях, решение требует, чтобы экземпляр дочернего класса создавался при вызове метода.
Способ сделать это — использовать метод класса в родительском классе, а также реализовать в родительском классе конструктор, который устанавливает поле. Например:
class TestParentClass():
@classmethod
def get_name(cls):
class_name = cls.__name__
return class_name
def __init__(self):
self.somefield = self.get_name()
class TestClass(TestParentClass):
pass
print(TestClass().somefield) # This prints 'TestClass'
somefield
может быть определен с помощью __init_subclass__
(который является особым методом класса без необходимости украшать его как таковой).
class TestParentClass:
def __init_subclass__(cls, **kwargs):
super().__init_subclass__(**kwargs)
cls.somefield = cls.__name__
class TestClass(TestParentClass):
pass
print(TestClass().somefield)
Почему бы вам не использовать свойство вместо метода?
class TestParentClass:
@property
def somefield(self):
return self.__class__.__name__
class TestClass(TestParentClass):
pass
Это должно печатать TestClass
при вызове print(TestClass().somefield)
.
Или, если вам нужно на уровне класса:
class classproperty(property): # noqa
def __get__(self, owner_self, owner_cls): # noqa
return self.fget(owner_cls) # noqa
class TestParentClass:
@classproperty
def somefield(cls):
class_name = cls.__name__
return class_name
class TestClass(TestParentClass):
pass
Это будет работать как для print(TestClass().somefield)
, так и для print(TestClass.somefield)
.