Я собираюсь разбить основные три (технически основные 2, потому что __format__
не очень часто реализуется).Я пройдусь по всем трем, а затем соберу все это в один хороший класс.
Наиболее распространенный __str__
:
Вот как вы хотите представить этот объект какstr
.Часто это менее детально, чем __repr__
и используется в основном для конечного пользователя.Например, если у нас есть класс person
, мы можем реализовать str
следующим образом:
class Person:
def __init__(self, name="John Smith"):
self.name = name
def __str__(self):
# This will return Hello my name is John Smith by default
return f"Hello my name is {self.name}"
Менее распространенный __repr__
:
Если честно, я реализую этобольше, чем я реализую str
для большинства проектов.Это должно возвращать представление объекта как str
таким образом, чтобы оно было полезным для разработчика вместо конечного пользователя и вызывалось через repr(my_obj)
.Если класс не реализует магический метод __str__
, то python попытается автоматически вызвать свой метод __repr__
при использовании str(my_obj)
(таким образом, вы можете сначала реализовать repr
и позже str
).Часто repr
класса возвращает способ воссоздания этого объекта, например:
class Person:
def __init__(self, name="John Smith"):
self.name = name
def __repr__(self):
return f"Person(name=\"{self.name}\")"
p = Person()
print(str(p)) # Prints "Person(name="John Smith")"
Проклятый потомок __format__
: [Я просто так его называю, потому что он используется так редко:)]
Чтобы понять это, я должен сначала объяснить некоторые вещи форматирования.Возможно, вы уже видели некоторые из этих вещей раньше или не видели.
Давайте используем фиктивный класс:
class Person:
def __init__(self, name="John Smith", age=22):
self.name = name
self.age = age
def __repr__(self):
return f'Person(name="{self.name}", age={self.age})'
def __str__(self):
# This will return Hello my name is John Smith by default
return str(self.name)
p = Person()
# This prints the str of p
print("{!s}".format(p)) # John Smith
# This prints the representation of p
print("{!r}".format(p)) # Person(name="John Smith", age=22)
Хорошо, так что вы можете отформатировать свой класс как str
или как repr
, но что, если вы хотите отформатировать его самостоятельно?путь?Большинству людей не нужно этого делать;но это сила Python, вы можете сделать что угодно .Мы можем создавать различные теги вместо r
и s
(хотя вместо 1010 * используется :
):
class Person:
def __init__(self, name="John Smith", age=22):
self.name = name
self.age = age
def __repr__(self):
return f'Person(name="{self.name}", age={self.age})'
def __str__(self):
# This will return Hello my name is John Smith by default
return str(self.name)
def __format__(self, format_spec):
# Make sure to choose a word not currently used (i.e. don't pick s, r, etc.)
if format_spec == 'age': # get a persons age
return f"{self.name} is {self.age} years old"
elif format_spec == 'birthday':
return "Yesterday"
return str(self) # A default case
p = Person()
# This prints the str of p
print("{!s}".format(p))
# This with representation of p
print("{!r}".format(p))
print("{:age}".format(p))
print("{:birthday}".format(p))
print(f"{p:age} and his birthday was {p:birthday}")
Очевидно, что это гораздо больше, чем могут ограничить мои ограниченные знанияно это должно быть хорошей общей областью:).
Есть некоторые пакеты, которые используют это, такие как datetime
.Если вам интересно узнать больше о силе формата Pyformat , то вы можете легко это понять: PyFormat .
Отказ от ответственности:
У меня нетбольшой опыт использования __format__
, поэтому я не могу предоставить хороший вариант использования (хотя вариант использования datetime не плохой).Здесь все просто для того, чтобы показать большую разницу между магическими методами str
, repr
и format
.Если я что-то не так (особенно в случае использования __format__
), пожалуйста, дайте мне знать, и я обновлю его.