Б41 Чистый Python. Тонкости программирования для профи. Спб.: Питер



Download 6,94 Mb.
Pdf ko'rish
bet19/80
Sana24.02.2022
Hajmi6,94 Mb.
#212875
1   ...   15   16   17   18   19   20   21   22   ...   80
Bog'liq
978544610803 Chisty Python Tonko

'переопределено' 
>>> t2._bar 
'переопределено' 
>>> t2.__baz 
AttributeError
"'ExtendedTest' object has no attribute '__baz'" 
Постойте, почему при попытке проверить значение 
t2.__baz
мы получаем 
исключение 
AttributeError
? Искажение имени наносит очередной удар! 
Оказывается, что этот объект вообще не имеет атрибута 
__baz
:
>>> dir(t2) 
['_ExtendedTest__baz', '_Test__baz', '__class__',
'__delattr__', '__dict__', '__dir__', '__doc__',
'__eq__', '__format__', '__ge__', '__getattribute__',
'__gt__', '__hash__', '__init__', '__le__', '__lt__',
'__module__', '__ne__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__',
'__sizeof__', '__str__', '__subclasshook__',
'__weakref__', '_bar', 'foo', 'get_vars']
Как видите, имя 
__baz
превратилось в 
_ExtendedTest__baz
, чтобы предот-
вратить случайное изменение. Но первоначальное имя 
_Test__baz
по-
прежнему на месте:
>>> t2._ExtendedTest__baz 
'переопределено' 
>>> t2._Test__baz 
42
Искажение имени с двойным символом подчеркивания для программи-
ста совершенно очевидно. Взгляните на следующий пример, который это 
подтверждает:
class ManglingTest:
def __init__(self):
self.__mangled = 'Привет' 


2 .4 . Подчеркивания, дандеры и другое 51
def get_mangled(self):
return self.__mangled 
>>> ManglingTest().get_mangled() 
'Привет' 
>>> ManglingTest().__mangled 
AttributeError
"'ManglingTest' object has no attribute '__mangled'" 
Распространяется ли искажение на имена методов? Конечно! Искажение 
имен затрагивает все имена, которые в контексте класса начинаются с двух 
символов подчеркивания (или «дандеров»):
class MangledMethod:
def __method(self):
return 42 
def call_it(self):
return self.__method() 
>>> MangledMethod().__method()
AttributeError
"'MangledMethod' object has no attribute '__method'" 
>>> MangledMethod().call_it() 
42 
Вот еще один, пожалуй, вызывающий удивление, пример искажения имен 
в действии:
_MangledGlobal__mangled = 23 
class MangledGlobal:
def test(self):
return __mangled 
>>> MangledGlobal().test() 
23
В этом примере я назначил 
_MangledGlobal__mangled
глобальной пе-
ременной. Затем к этой переменной я обратился в контексте класса 
MangledGlobal
. Из-за искажения имен я смог сослаться на глобальную 
переменную 
_MangledGlobal__mangled
просто как на 
__mangled
внутри 
метода 
test()
класса.


52 Глава 2 • Шаблоны для чистого Python
Интерпретатор Python автоматически расширил имя 
__mangled
до 
_MangledGlobal__mangled
, потому что оно начинается с двух символов 
подчеркивания. Это показывает, что искажение имен точно не связано 
с атрибутами класса. Оно относится к любому имени, начинающемуся 
с двух символов подчеркивания, которое используется в контексте 
класса.
Уф-ф! Многовато, надо переварить.
Буду с вами честен: я написал эти примеры и объяснения не сразу из 
головы. Чтобы это сделать, мне потребовалось время на исследование 
и редактирование. Я использую Python много лет, однако правила и вот 
такие особые случаи, как этот, не крутятся у меня в мозгу постоянно.
Для программиста иногда самым важным навыком является умение 
«распознавать шаблоны» (образы, паттерны) и понимать, где их нужно 
искать. Если в этом месте вы чувствуете себя несколько подавленными, 
не волнуйтесь. Отдохните и поэкспериментируйте с несколькими при-
мерами из этого раздела.
Пусть эти принципы впитаются как следует, чтобы вы наконец осознали 
общую идею искажения имен и некоторые другие формы поведения, ко-
торые я вам показал. Если однажды вы столкнетесь с ними «в полях», то 
хотя бы будете знать, что именно искать в документации.
Экскурс: что такое дандеры?
Если вы слышали разговор опытных питонистов о Python или при-
сутствовали при обсуждении на конференциях, то, возможно, слышали 
термин дандер (dunder). Вам интересно, что же это такое? Ладно, вот 
ответ.
В сообществе Python двойные символы подчеркивания часто называют 
«дандерами» (dunders — это сокращение от англ. double underscores). При-
чина в том, что в исходном коде Python двойные символы подчеркивания 
встречаются довольно часто, и, чтобы не изнурять свои жевательные 
мышцы, питонисты нередко сокращают термин «двойное подчеркивание», 
сводя его до «дандера».


2 .4 . Подчеркивания, дандеры и другое 53
Например, переменная 
__baz
будет произноситься как «дандер baz». Ана-
логичным образом, метод 
__init__
звучит как «дандер init», хотя будет 
логичным предположить, что так: «дандер init дандер».
Но это всего лишь еще одна из причуд среди прочих согласованных пра-
вил именования. Для разработчиков Python это все равно что секретное 
рукопожатие.
4 . Двойной начальный и замыкающий символ 
подчеркивания: __var__
Пожалуй, это удивляет, но искажение имен не применяется, если имя 
начинается и заканчивается двойными символами подчеркивания. Ин-
терпретатор Python не трогает переменные, окруженные префиксом 
и постфиксом, которые состоят из двойных символов подчеркивания:
class PrefixPostfixTest:
def __init__(self):
self.__bam__ = 42 
>>> PrefixPostfixTest().__bam__ 
42
Однако имена, у которых есть начальный и замыкающий двойной символ 
подчеркивания, в языке зарезервированы для специального применения. 
Это правило касается таких имен, как метод 
__init__
для конструкторов 
объектов или метод 
__call__
, который делает объекты вызываемыми.
Эти дандер-методы часто упоминаются как магические методы, однако 
в сообществе Python многим разработчикам, включая меня, это слово не 
нравится. Такое название подразумевает, что применение дандер-методов 
не приветствуется, и это абсолютно не соответствует действительности. 
В Python они представляют собой ключевое функциональное средство 
и должны применяться по мере необходимости. В них нет ничего «маги-
ческого» или тайного.
Тем не менее в контексте согласованных правил именования лучше воз-
держаться от использования имен, которые начинаются и заканчиваются 


54 Глава 2 • Шаблоны для чистого Python
двойными символами подчеркивания, в своих собственных программах — 
во избежание конфликтов с последующими версиями языка Python.
5 . Одинарный символ подчеркивания: _
По договоренности одинарный автономный символ подчеркивания ино-
гда используется в качестве имени, чтобы подчеркнуть, что эта перемен-
ная временная или незначительная.
Например, в приведенном ниже цикле нам не нужен доступ к нарастающе-
му индексу, и мы можем применить «
_
», чтобы показать, что этот символ 
подчеркивания является лишь временным значением:
>>> for _ in range(32):
... print('Привет, Мир.')
Одинарные символы подчеркивания также можно применять в распа-
ковке выражений, обозначая таким образом «неважную» переменную, 
чтобы проигнорировать отдельные значения. И снова: смысл одинарного 
подчеркивания существует только по договоренности, и оно не запускает 
особых форм поведения в синтаксическом анализаторе Python. Одинар-
ный символ подчеркивания — это просто имя допустимой переменной, 
которое иногда используется с этой целью.
В следующем ниже примере исходного кода я распаковываю кортеж в от-
дельные переменные, но я заинтересован только в значениях полей 
color
и 
mileage
. Однако для того, чтобы выражение распаковки было успешным, 
мне нужно назначить переменным все содержащиеся в кортеже значения. 
Именно тут в качестве переменной-заполнителя пригодится символ «
_
»:
>>> car = ('красный', 'легковой автомобиль', 12, 3812.4) 
>>> color, _, _, mileage = car 
>>> color 
'красный' 
>>> mileage 
3812.4 
>>> _ 
12


2 .4 . Подчеркивания, дандеры и другое 55
Помимо его применения в качестве временной переменной, символ «
_
» 
является специальной переменной в большинстве интерпретаторов Python, 
работающих в цикле чтение-вычисление-печать (REPL). Она представляет 
в них результат последнего выражения, вычисленного интерпретатором.
Это удобно, если вы работаете в сеансе интерпретатора и хотите получить 
доступ к результату предыдущего вычисления:
>>> 20 + 3 
23 
>>> _ 
23 
>>> print(_) 
23
Это также удобно, если вы конструируете объекты на лету и хотите взаи-
модействовать с ними, не назначая им имени перед этим:
>>> list() 
[] 
>>> _.append(1) 
>>> _.append(2) 
>>> _.append(3) 
>>> _ 
[1, 2, 3]
Ключевые выводы
‰
‰

Download 6,94 Mb.

Do'stlaringiz bilan baham:
1   ...   15   16   17   18   19   20   21   22   ...   80




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©hozir.org 2024
ma'muriyatiga murojaat qiling

kiriting | ro'yxatdan o'tish
    Bosh sahifa
юртда тантана
Боғда битган
Бугун юртда
Эшитганлар жилманглар
Эшитмадим деманглар
битган бодомлар
Yangiariq tumani
qitish marakazi
Raqamli texnologiyalar
ilishida muhokamadan
tasdiqqa tavsiya
tavsiya etilgan
iqtisodiyot kafedrasi
steiermarkischen landesregierung
asarlaringizni yuboring
o'zingizning asarlaringizni
Iltimos faqat
faqat o'zingizning
steierm rkischen
landesregierung fachabteilung
rkischen landesregierung
hamshira loyihasi
loyihasi mavsum
faolyatining oqibatlari
asosiy adabiyotlar
fakulteti ahborot
ahborot havfsizligi
havfsizligi kafedrasi
fanidan bo’yicha
fakulteti iqtisodiyot
boshqaruv fakulteti
chiqarishda boshqaruv
ishlab chiqarishda
iqtisodiyot fakultet
multiservis tarmoqlari
fanidan asosiy
Uzbek fanidan
mavzulari potok
asosidagi multiservis
'aliyyil a'ziym
billahil 'aliyyil
illaa billahil
quvvata illaa
falah' deganida
Kompyuter savodxonligi
bo’yicha mustaqil
'alal falah'
Hayya 'alal
'alas soloh
Hayya 'alas
mavsum boyicha


yuklab olish