Перейти к содержимому

Def str self python что это

  • автор:

Def str self python что это

Магия вне Хогвартса: рассказываем о том, что такое Python 3 магические методы в блоге студии web-разработки YuSMP Group. В языке программирования существуют специальные приемы, которые упрощают работу с кодом. Каждая конструкция обозначается словом, которое начинается и заканчивается двойным подчеркиванием, например, __add__ .

Их также называют методами Дандера. Python магические методы класса не предназначены для непосредственного вызова разработчиком, но вызов происходит внутри класса при определенном действии. Например, когда вы добавляете два числа с помощью оператора внутри __add__() будет вызываться соответствующий прием.

Магические методы Python: список популярных конструкций

Магический метод add Python

Ранее упомянутый __add__ — это конструкция, которая вызывается, когда мы складываем два числа с помощью оператора. Посмотрите пример ниже.

Как видите, при выполнении num+10 оператор + вызывает __add__(10) . Вы также можете вызвать num. __add__(5) напрямую, что даст тот же результат. Однако, как упоминалось ранее, такие приемы не предназначены для прямого вызова, а внутренне, через некоторые другие действия.

Такие конструкции чаще всего используются для определения перегруженного поведения предопределенных операторов в Python. Например, арифметические операторы по умолчанию работают с числовыми операндами. Это означает, что числовые объекты должны использоваться вместе с такими операторами, как +, -, *, / и т. д. Оператор + также определяется как оператор конкатенации в классах строк, списков и кортежей. Можно сказать, что оператор + перегружен.

Чтобы сделать перегруженное поведение доступным в вашем собственном классе, соответствующий прием должен быть переопределен. Например, чтобы использовать оператор + с объектами определенного пользователем класса, он должен включать в себя __add__() .

Давайте посмотрим, как реализовать и использовать некоторые из важнейших конструкций в нашем контексте.

Магический метод new Python

В таких языках, как Java и C#, оператор new используется для создания нового экземпляра класса. В Python __new__() неявно вызывается перед __init__() методом. Конструкция __new__() возвращает новый объект, который затем инициализируется с помощью __init__() .

class Employee: def __new__(cls): print ("__new__ magic method is called") inst = object.__new__(cls) return inst def __init__(self): print ("__init__ magic method is called") self.name='Satya' 

В приведенном выше примере будет получен следующий вывод при создании экземпляра Employee класса.

>>> emp = Employee()

__new__ вызывается магический метод

__init__ вызывается магический метод

Таким образом, __new__() вызывается перед __init__() .

Магический метод str Python

Еще одна полезная конструкция — __str__() . Она необходима, чтобы возвращать печатное строковое представление любого определяемого пользователем класса. Мы видели str()встроенную функцию, которая возвращает строку из параметра объекта. Например, str(12)возвращает «12».

При вызове он вызывает __str__() в классе int.

Давайте теперь переопределим __str__() в классе Employee, чтобы он возвращал строковое представление его объекта.

class Employee: def __init__(self): self.name='Swati' self.salary=10000 def __str__(self): return 'name='+self.name+' salary=$'+str(self.salary)

Посмотрите, как str () функция внутренне вызывает __str__() метод, определенный в классе Employee. Вот почему это называется волшебным методом!

__ge__() метод

В класс расстояния добавлен следующий метод для перегрузки >=оператора.

class distance: def __init__(self, x=None,y=None): self.ft=x self.inch=y def __ge__(self, x): val1=self.ft*12+self.inch val2=x.ft*12+x.inch if val1>=val2: return True else: return False 

Этот прием вызывается при использовании >=оператора и возвращает значение True или False. Соответственно, может отображаться соответствующее сообщение.

Магический метод lt python

__lt__ — это одна из конструкций, которая используется для определения или реализации функциональности оператора «меньше чем» «

Синтаксис: __lt__ (я, объект)

  • self: ссылка на объект.
  • obj: это объект, который в дальнейшем будет сравниваться с другим объектом.

Возвращает: возвращает True или False в зависимости от сравнения.

Примечание. Мы можем вернуть любой тип значения из метода __lt__ , а позже мы можем преобразовать его в логическое значение с помощью встроенного метода bool() , т.е.

Магический метод call python

Метод Python __call__ делает класс вызываемым, поэтому вы можете вызывать объекты класса как обычную функцию. Например, если вы определяете __call__(self) объект x класса X, вы можете назвать его так: x(). Возвращаемое значение вызываемого объекта является возвращаемым значением __call__() метода.

Следующий фрагмент кода делает пользовательский класс Person доступным для вызова, предоставляя реализацию магического метода __call__() , который принимает два аргумента:

  • self — ссылка на сам объект. Он автоматически передается в функцию Python — вам не нужно указывать аргумент самостоятельно.
  • other — дополнительный аргумент (например, строка) для предоставления пользовательского приветствия.

С помощью этой реализации мы теперь можем создать вызываемый объект alice и вызывать его следующим образом: alice() .

class Person: def __call__(self, other): return f'Hi ' alice = Person() print(alice('Bob')) # Hi Bob 

Магический метод enter python и магический метод exit python

Python вызывает __enter__() при запуске with блока, тогда как __exit__() вызывается в конце. Объект, реализующий приемы __enter__() и __exit__() , называется менеджером контекста.Определив эти конструкции, вы можете создать свой собственный контекстный менеджер.

Класс MySecretConnection: def init ( я, URL ) : self.url = URL-адрес защита enter ( самостоятельно ) : печать ( 'вход' , self.url ) def exit ( self, exc_type, exc_val, exc_tb ) : print ( 'уходя' , self.url ) с MySecretConnection как finxter: # Вызывается finxter.__enter__() проходить # Вызывается finxter.__exit__() 
  • Мы определяем пользовательский класс MySecretConnection. Это может удерживать любое соединение в вашем скрипте Python, поэтому вы можете легко очистить веб-сайт или сделать все, что захотите.
  • Определяем __enter__() и __exit__() magic, чтобы сделать класс MySecretConnection менеджером контекста, т. е. разрешить его использование в with операторе.
  • Создаем with оператор, назначая конкретный экземпляр MySecretConnection, который подключается к нашему приложению — головоломке Python, переменной finxter.

Резюме

Магические методы сравнения Python нужно понимать хотя бы для того, чтобы понимать как работает язык. На практике разработчики используют готовые решения, которые помогают быстрее создавать продукты. Питон — важная технология веб-разработки, которая также используется и для написание мобильного ПО. Веб-услуги и разработка в YuSMP Group включает в свой стек Python, чтобы создавать качественные и производительные продукты, примеры можно увидеть здесь — кейсы YuSMP Group. Свяжитесь с через наши контакты, чтобы получить первую бесплатную консультацию по вашему проекту.

Строковые представления экземпляров класса: методы __str__ и __repr__

Итак, вы только что создали свой первый класс в Python, аккуратный маленький класс, который инкапсулирует игральную карту:

class Card: def __init__(self, suit, pips): self.suit = suit self.pips = pips 

В другом месте вашего кода вы создаете несколько экземпляров этого класса:

ace_of_spades = Card('Spades', 1) four_of_clubs = Card('Clubs', 4) six_of_hearts = Card('Hearts', 6)

Вы даже создали список карт, чтобы представить «руку»:

my_hand = [ace_of_spades, four_of_clubs, six_of_hearts] 

Теперь, во время отладки, вы хотите посмотреть, как выглядит ваша рука, поэтому вы делаете то, что естественно, и пишете:

print(my_hand) 

Но то, что вы получите, — это кучка бреда:

В замешательстве вы пытаетесь просто напечатать одну карту:

print(ace_of_spades) 

И снова, вы получите этот странный вывод:

Не бойся Мы собираемся это исправить.

Однако сначала важно понять, что здесь происходит. Когда вы писали print(ace_of_spades) вы сказали Python вы хотели, чтобы напечатать информацию о Card , например ваш код вызывающего ace_of_spades .И, честно говоря, это так.

Этот вывод состоит из двух важных бита: type объекта и объекта id .Одна вторая часть (число шестнадцатеричного) достаточно , чтобы однозначно идентифицировать объект в момент print вызова. [1]

Что на самом деле произошло, так это то, что вы попросили Python «выразить словами» суть этого объекта и затем показать его вам. Более явная версия того же механизма может быть:

string_of_card = str(ace_of_spades) print(string_of_card) 

В первой строке, вы пытаетесь превратить Card экземпляр в строку, а во втором вы его отображения.

Эта проблема

Проблема Вы сталкиваетесь возникает из — за того , что, в то время как вы сказали , Python все , что требовалось знать о Card классе для вас , чтобы создать карты, вы не сказали ему , как вы хотели Card экземпляров должны быть преобразованы в строки.

И так как он не знал, когда вы (неявно) писал str(ace_of_spades) , он дал вам то , что вы видели, родовое представление Card экземпляра.

Решение (часть 1)

Но мы можем сказать , Python , как мы хотим , чтобы экземпляры наших пользовательских классов , которые будут преобразованы в строки. И то , как мы делаем это с __str__ «Dunder» (для двойного подчеркивания) или метода «магического».

Всякий раз , когда вы говорите Python , чтобы создать строку из экземпляра класса, он будет искать __str__ методу на классе, и назвать его.

Рассмотрим следующий, обновленную версию нашего Card класса:

class Card: def __init__(self, suit, pips): self.suit = suit self.pips = pips def __str__(self): special_names = card_name = special_names.get(self.pips, str(self.pips)) return "%s of %s" % (card_name, self.suit)

Вот, сейчас мы определили __str__ метод на наших Card класса , который, после того, как простой поиск в словаре для фигурных карт, возвращает строку , отформатированную однако мы решаем.

(Обратите внимание , что «возвращает» жирный шрифт здесь, чтобы подчеркнуть важность возвращения строки, а не просто напечатать его. Печать может показаться на работу, но тогда вам придется карта распечатывается , когда вы сделали что — то вроде str(ace_of_spades) , даже без вызова функции печати в главной программе. Таким образом , чтобы быть ясно, убедитесь , что __str__ возвращает строку.).

__str__ метод представляет собой метод, так что первый аргумент будет self , и это не должно ни принимать, ни быть переданы аргументы вывода дополнительных.

Возвращаясь к нашей проблеме отображения карты в более удобной для пользователя форме, если мы снова запустим:

ace_of_spades = Card('Spades', 1) print(ace_of_spades)

Мы увидим, что наш вывод намного лучше:

Ace of spades

Так здорово, мы закончили, верно?

Ну просто , чтобы покрыть наши базы, давайте двойную проверку , что мы решили первый вопрос , который мы столкнулись, печать списка Card экземпляров, в hand .

Итак, мы перепроверили следующий код:

my_hand = [ace_of_spades, four_of_clubs, six_of_hearts] print(my_hand) 

И, к нашему удивлению, мы снова получаем эти забавные шестнадцатеричные коды:

В чем дело? Мы сказали , Python , как мы хотели , чтобы наши Card экземпляров , которые будут отображаться, почему он , по- видимому , кажется, забыли?

Решение (часть 2)

Механизм закулисности немного отличается, когда Python хочет получить строковое представление элементов в списке. Оказывается, Python не заботится о __str__ для этой цели.

Вместо этого, он ищет другой метод, __repr__ , и если это не найдено, он возвращается на «шестнадцатеричном вещь». [2]

То есть ты говоришь, что мне нужно сделать два метода, чтобы сделать то же самое? Один, когда я хочу , чтобы print свою карточку сама по себе , а другой , когда он в какойто контейнер?

Нет, но сначала давайте посмотрим на то , что наш класс был бы, если бы мы должны были реализовать как __str__ и __repr__ методы:

class Card: special_names = def __init__(self, suit, pips): self.suit = suit self.pips = pips def __str__(self): card_name = Card.special_names.get(self.pips, str(self.pips)) return "%s of %s (S)" % (card_name, self.suit) def __repr__(self): card_name = Card.special_names.get(self.pips, str(self.pips)) return "%s of %s (R)" % (card_name, self.suit)

Здесь, реализация этих двух методов __str__ и __repr__ точно так же, за исключением того, что различие между этими двумя методами, (S) , добавляется в строки , возвращаемых __str__ и (R) добавляется к строкам возвращаемых __repr__ .

Обратите внимание , что так же , как наш __str__ метод, __repr__ не принимает никаких аргументов и возвращает строку.

Теперь мы можем видеть, какой метод отвечает за каждый случай:

ace_of_spades = Card('Spades', 1) four_of_clubs = Card('Clubs', 4) six_of_hearts = Card('Hearts', 6) my_hand = [ace_of_spades, four_of_clubs, six_of_hearts] print(my_hand) # [Ace of Spades (R), 4 of Clubs (R), # 6 of Hearts (R)] print(ace_of_spades) # Ace of Spades (S)

Как было покрыто, то __str__ метод вызывается , когда мы проходили мимо нашей Card экземпляра print и __repr__ метод вызывается , когда мы проходили мимо список наших экземпляров для print .

На этом этапе стоит отметить, что, как мы можем явно создать строку из экземпляра пользовательского класса с использованием str() , как мы делали раньше, мы можем также явно создать строковое представление нашего класса с встроенной функцией называется repr() .

str_card = str(four_of_clubs) print(str_card) # 4 of Clubs (S) repr_card = repr(four_of_clubs) print(repr_card) # 4 of Clubs (R)

И кроме того, если определено, мы могли бы назвать методы напрямую (хотя это кажется немного неясным и ненужным):

print(four_of_clubs.__str__()) # 4 of Clubs (S) print(four_of_clubs.__repr__()) # 4 of Clubs (R)

О тех дублированных функциях .

Разработчики Python поняли, в случае , если вы хотели идентичные строки должны быть возвращены из str() и repr() вы могли бы функционально дублирующие методы — то , что никто не любит.

Таким образом, вместо этого существует механизм для устранения необходимости в этом. Один я пробрался к тебе до этого момента. Оказывается, что если класс реализует __repr__ метод , но не __str__ метод, и вы передаете экземпляр этого класса str() (независимо от того , явно или неявно), Python будет Откат на вашем __repr__ реализации и использовать.

Так, чтобы было ясно, рассмотрим следующую версию Card класса:

class Card: special_names = def __init__(self, suit, pips): self.suit = suit self.pips = pips def __repr__(self): card_name = Card.special_names.get(self.pips, str(self.pips)) return "%s of %s" % (card_name, self.suit)

Обратите внимание , эта версия только реализует __repr__ метод. Тем не менее, вызовы str() результат в удобной версии:

print(six_of_hearts) # 6 of Hearts (implicit conversion print(str(six_of_hearts)) # 6 of Hearts (explicit conversion) 

как это делают вызовы repr() :

print([six_of_hearts]) #[6 of Hearts] (implicit conversion) print(repr(six_of_hearts)) # 6 of Hearts (explicit conversion) 

Резюме

Для того , чтобы вам расширить возможности ваших экземпляров классов , чтобы «показать себя» в удобных способах, вы хотите , чтобы рассмотреть вопрос об осуществлении по крайней мере вашего класс __repr__ метода. Если память служит, во время разговора Raymond Hettinger сказал , что обеспечение реализации классов __repr__ является одной из первых вещей , которые он смотрит на Python, делая анализ кода, и теперь должно быть ясно , почему. Количество информации , которую вы могли бы добавить к отладке заявления, отчеты об ошибках, или лог — файлы с помощью простого метода является подавляющим , когда по сравнению с ничтожными, и часто менее чем полезно (тип, идентификатор) информации , которая задается по умолчанию.

Если вы хотите , различные представления для того, когда, например, внутри контейнера, вы хотите реализовать как __repr__ и __str__ методы. (Подробнее о том, как вы можете использовать эти два метода по-разному ниже).

Реализованы оба метода, стиль eval-round-trip __repr __ ()

class Card: special_names = def __init__(self, suit, pips): self.suit = suit self.pips = pips # Called when instance is converted to a string via str() # Examples: # print(card1) # print(str(card1) def __str__(self): card_name = Card.special_names.get(self.pips, str(self.pips)) return "%s of %s" % (card_name, self.suit) # Called when instance is converted to a string via repr() # Examples: # print([card1, card2, card3]) # print(repr(card1)) def __repr__(self): return "Card(%s, %d)" % (self.suit, self.pips) 

Методы __str__() и __repr__() в Python

В этой статье мы поговорим о специальных методах __str__() и __repr__() в модели данных Python . Методы __str__() и __repr__() могут быть полезны при отладке кода Python путем логирования или вывода полезной информации об объекте.

Специальные методы Python начинаются и заканчиваются двойным подчеркиванием и потому неофициально называются dunder методами (где dunder – сокращение от double underscore) . Данные методы являются базовыми для встроенных операторов и функций Python. Прямого вызова методов dunder следует избегать; лучше сначала реализовывать их в классах, а затем использовать встроенные функции, которые их вызывают, типа str() и repr().

Разница между __str__() и __repr__()

Метод __str__() возвращает удобочитаемое (или неформальное) строковое представление объекта. Этот метод вызывается встроенными функциями print(), str() и format(). Если вы не определяете метод __str__() для класса, то встроенная реализация объекта будет вызывать метод __repr__().

Метод __repr__() возвращает более информативное (официальное) строковое представление объекта. Этот метод вызывается встроенной функцией repr(). Если возможно, возвращаемая строка должна быть представлена валидным выражением Python, которое можно использовать для воссоздания объекта. В любом случае строка должна быть информативной и однозначной.

Как правило, строка __str__() предназначена для пользователей, а __repr__() — для разработчиков.

Примеры встроенных __str__() и __repr__()

Примеры в этом разделе прямо вызывают методы __str__() и __repr__() в демонстрационных целях.

Класс datetime.datetime — это встроенный класс Python, который по умолчанию реализует методы __str__() и __repr__().

В следующем примере кода показаны строки, возвращаемые стандартной реализацией методов __str__() и __repr__() для объекта datetime.datetime:

import datetime mydate = datetime.datetime.now() print("__str__() string: ", mydate.__str__()) print("str() string: ", str(mydate)) print("__repr__() string: ", mydate.__repr__()) print("repr() string: ", repr(mydate))

Вывод будет следующим:

__str__() string: 2023-01-27 09:50:37.429078 str() string: 2023-01-27 09:50:37.429078 __repr__() string: datetime.datetime(2023, 1, 27, 9, 50, 37, 429078) repr() string: datetime.datetime(2023, 1, 27, 9, 50, 37, 429078)

Вывод показывает, что функция str() вызывает метод __str__() и возвращает удобочитаемую строку, а функция repr() вызывает метод __repr__() и возвращает более информативную строку, которую можно использовать для воссоздания объекта. Фактически для создания нового объекта из строки вы можете использовать функцию repr() с функцией eval():

import datetime mydate1 = datetime.datetime.now() mydate2 = eval(repr(mydate1)) print("mydate1 repr() string: ", repr(mydate1)) print("mydate2 repr() string: ", repr(mydate2)) print("the values of the objects are equal: ", mydate1==mydate2)
mydate1 repr() string: datetime.datetime(2023, 1, 26, 9, 43, 24, 479635) mydate2 repr() string: datetime.datetime(2023, 1, 26, 9, 43, 24, 479635) the values of the objects are equal: True

Код в предыдущем примере создает объект mydate2 из строки repr() для mydate1, а затем проверяет, равны ли значения обоих объектов.

Примеры __str__() и __repr__() в новых классах

Когда вы создаете класс, вы должны реализовать как минимум метод __repr__(), чтобы возвращать полезную информацию, когда встроенные функции используют __repr__().

Следующий класс не реализует ни метод __str__(), ни __repr()__:

class Ocean: def __init__(self, sea_creature_name, sea_creature_age): self.name = sea_creature_name self.age = sea_creature_age c = Ocean('Jellyfish', 5) print(str(c)) print(repr(c))

При использовании функций str() и repr() вывод будет таким:

В предыдущем примере показано, что реализация __repr()__ по умолчанию возвращает строку, содержащую только класс и идентификатор объекта в шестнадцатеричном формате, что не очень полезно. Обратите внимание, что str() и repr() возвращают одно и то же: такое происходит, если метод __str__() не реализован — тогда функция str() вызывает метод __repr__().

Обновите класс Ocean, добавив реализации методов __str__() и __repr__():

class Ocean: def __init__(self, sea_creature_name, sea_creature_age): self.name = sea_creature_name self.age = sea_creature_age def __str__(self): return f'The creature type is self.name> and the age is self.age>' def __repr__(self): return f'Ocean(\'self.name>\', self.age>)' c = Ocean('Jellyfish', 5) print(str(c)) print(repr(c))

В результате получим:

The creature type is Jellyfish and the age is 5 Ocean('Jellyfish', 5)\

Реализация __str__() в предыдущем примере возвращает удобочитаемую строку, предоставляющую пользователю релевантные сведения об объекте. В то же время реализация __repr__() возвращает строку, являющуюся допустимым выражением Python, которое можно использовать для воссоздания объекта: Ocean(‘Jellyfish’, 5) . В примере используются f-строки, но вы можете форматировать строки так, как удобнее вам.

Заключение

В этой статье мы на примерах продемонстрировали различия между специальными методами __str__() и __repr__() и реализовали их в классах, чтобы их не нужно было вызывать напрямую.

Разница между __str__ и __repr__ в Python

Часто при работе с объектами в Python возникает потребность в представлении объектов в виде строк. Это может быть полезно для отладки, логирования или просто для вывода информации о объекте. В Python для этого существуют два специальных метода: __str__ и __repr__ .

Предположим, что есть класс Cat , который имеет атрибуты name и age . Можно было бы представить объект этого класса в виде строки следующим образом:

class Cat: def __init__(self, name, age): self.name = name self.age = age def __str__(self): return f'Cat(name=, age=)'

Тогда при попытке преобразовать объект класса Cat в строку, будет получено представление объекта в виде Cat(name=Fluffy, age=5) .

Однако, что если нужно получить более детальное или иное представление объекта, которое будет удобно использовать для отладки или логирования? Здесь на помощь приходит метод __repr__ .

Метод __repr__ предназначен для создания «официального» строкового представления объекта, которое может быть использовано для воссоздания объекта при помощи функции eval() . Вернувшись к нашему примеру с классом Cat , можно добавить метод __repr__ следующим образом:

class Cat: def __init__(self, name, age): self.name = name self.age = age def __str__(self): return f'Cat(name=, age=)' def __repr__(self): return f'Cat(name=, age=)'

Теперь при вызове repr() для объекта класса Cat , будет получено представление объекта в виде Cat(name=’Fluffy’, age=5) , которое может быть использовано для воссоздания объекта.

Важно отметить, что если для класса определен только метод __repr__ , то он будет использован и при вызове str() . Однако, если определены оба метода, __str__ и __repr__ , то при вызове str() будет использован __str__ , а при вызове repr() — __repr__ .

Итак, главное отличие между __str__ и __repr__ в Python заключается в их назначении: __str__ предназначен для создания «приятного» для чтения представления объекта, в то время как __repr__ предназначен для создания «официального» представления, которое может быть использовано для воссоздания объекта.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *