Как проверить, реализуется ли __str__ объектом
Я хочу динамически реализовать метод __str__
на объекте, если объект еще не реализовал его.
Я пытаюсь использовать hasattr(obj, '__str__')
, он всегда возвращает мне истину, так как берет его из класса объекта.
Есть ли способ определить, действительно ли объект реализует __str__
?
Я знаю, что могу использовать inspect.getmembers(obj)
, но я ищу более питонический способ
EDIT
class Employee(object):
def __init__(self, name, age, emp_code):
self.name = name
self.age = age
self.emp_code = emp_code
Test
e = Employee("A", 23, "E1")
print hasattr(e, '__str__')
>> True
Я хочу чек, который возвращает False
вместо выбора метода, унаследованного от object
.
Ответы
Ответ 1
Так как вы хотите проверить, имеет ли он реализацию __str__
, которая не является значением по умолчанию object.__str__
. Поэтому вы можете сделать это:
Foo.__str__ is not object.__str__
Чтобы проверить с помощью экземпляров объектов, вам нужно проверить класс:
type(f).__str__ is not object.__str__
Это также будет работать, даже если Foo не реализует непосредственно __str__
, но унаследовал его от другого класса, чем object
, который, кажется, вам нужен.
Ответ 2
Любой объект, наследующий базу object
, будет иметь метод __str__
, поэтому тестирование, если оно существует, ничтожно.
Вы можете сохранить атрибут флага на объекте и проверить вместо этого:
if not getattr(obj, 'has_str_override_flag'):
override_str_here(obj)
setattr(obj, 'has_str_override_flag', True)
Ответ 3
В вашем объекте есть __dict__, который содержит все методы и переменные, которые есть у объекта. Вы можете проверить, есть ли у данного объекта метод __str __(), реализованный
'__str__' in Employee.__dict__
или
'__str__' in vars(Employee)
Между vars() и __dict__ нет разницы, просто vars() более Pythonic.
Ответ 4
Оказывается, что встроенные типы полагаются на object.__str__
для их (умного) форматирования. Я действительно хотел только исключить бесполезные строки, такие как <__main__.Foo object at 0x10299d390>
, и по-прежнему правильно печатать dict и другие типы. Мое решение:
objre = re.compile(r"<.* object at 0x[0-9a-f]+>")
if objre.fullmatch(str(obj)):
# Do smarter formatting
Это не отразит форматирование модулей, функций и т.д. по умолчанию, для которого вместо этого можно было бы показать исходный код через inspect.getsource()
, но я все равно не отображаю их в моем инспекторе переменных.
Ответ 5
Используйте type (e).__ dict __. Get (method_name), чтобы избежать KeyError, если method_name не существует в классе при использовании type (e).__ dict __ [method_name]
e = Employee("A", 23, "E1")
if type(e).__dict__.get('__str__'):
print('__str__ implemented')
else:
print('__str__ not implemented')