mirror of
https://github.com/satwikkansal/wtfpython
synced 2024-11-22 02:54:25 +01:00
Translate Name mangling example
This commit is contained in:
parent
3b9d9bdcd1
commit
b5c20d02ea
77
translations/README-ru.md
vendored
77
translations/README-ru.md
vendored
@ -3222,3 +3222,80 @@ Ellipsis
|
|||||||
- Интересно, что хэш `float('-inf')` - "-10⁵ x π" в Python 3, тогда как в Python 2 - "-10⁵ x e".
|
- Интересно, что хэш `float('-inf')` - "-10⁵ x π" в Python 3, тогда как в Python 2 - "-10⁵ x e".
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
||||||
|
### ▶ Давайте искажать
|
||||||
|
<!-- Example ID: 37146d2d-9e67-43a9-8729-3c17934b910c --->
|
||||||
|
1\.
|
||||||
|
```py
|
||||||
|
class Yo(object):
|
||||||
|
def __init__(self):
|
||||||
|
self.__honey = True
|
||||||
|
self.bro = True
|
||||||
|
```
|
||||||
|
|
||||||
|
**Результат:**
|
||||||
|
```py
|
||||||
|
>>> Yo().bro
|
||||||
|
True
|
||||||
|
>>> Yo().__honey
|
||||||
|
AttributeError: 'Yo' object has no attribute '__honey'
|
||||||
|
>>> Yo()._Yo__honey
|
||||||
|
True
|
||||||
|
```
|
||||||
|
|
||||||
|
2\.
|
||||||
|
```py
|
||||||
|
class Yo(object):
|
||||||
|
def __init__(self):
|
||||||
|
# Попробуем симметричные двойные подчеркивания в названии атрибута
|
||||||
|
self.__honey__ = True
|
||||||
|
self.bro = True
|
||||||
|
```
|
||||||
|
|
||||||
|
**Результат:**
|
||||||
|
```py
|
||||||
|
>>> Yo().bro
|
||||||
|
True
|
||||||
|
|
||||||
|
>>> Yo()._Yo__honey__
|
||||||
|
Traceback (most recent call last):
|
||||||
|
File "<stdin>", line 1, in <module>
|
||||||
|
AttributeError: 'Yo' object has no attribute '_Yo__honey__'
|
||||||
|
```
|
||||||
|
|
||||||
|
Почему обращение к `Yo()._Yo__honey` сработало?
|
||||||
|
|
||||||
|
3\.
|
||||||
|
|
||||||
|
```py
|
||||||
|
_A__variable = "Some value"
|
||||||
|
|
||||||
|
class A(object):
|
||||||
|
def some_func(self):
|
||||||
|
return __variable # переменная еще не инициализирована
|
||||||
|
```
|
||||||
|
|
||||||
|
**Результат:**
|
||||||
|
```py
|
||||||
|
>>> A().__variable
|
||||||
|
Traceback (most recent call last):
|
||||||
|
File "<stdin>", line 1, in <module>
|
||||||
|
AttributeError: 'A' object has no attribute '__variable'
|
||||||
|
|
||||||
|
>>> A().some_func()
|
||||||
|
'Some value'
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### 💡 Объяснение:
|
||||||
|
|
||||||
|
* [Искажение имени](https://en.wikipedia.org/wiki/Name_mangling) используется для предотвращения коллизий имен между различными пространствами имен.
|
||||||
|
* В Python интерпретатор изменяет (mangles) имена членов класса, начинающиеся с `__` (двойное подчеркивание, оно же "дундер") и не заканчивающиеся более чем одним подчеркиванием в конце, добавляя перед ними `_NameOfTheClass`.
|
||||||
|
* Таким образом, чтобы получить доступ к атрибуту `__honey` в первом фрагменте, мы должны были добавить `_Yo` спереди, что предотвратило бы конфликты с тем же атрибутом `name`, определенным в любом другом классе.
|
||||||
|
* Но почему тогда это не сработало во втором фрагменте? Потому что при манипулировании именами исключаются имена, заканчивающиеся двойным подчеркиванием.
|
||||||
|
* Третий фрагмент также является следствием манипулирования именами. Имя `__variable` в операторе `return __variable` было искажено до `_A__variable`, что также является именем переменной, которую мы объявили во внешней области видимости.
|
||||||
|
* Кроме того, если длина искаженного имени превышает 255 символов, произойдет усечение (truncation).
|
||||||
|
|
||||||
|
---
|
||||||
|
---
|
||||||
|
Loading…
Reference in New Issue
Block a user