Skip to content

Commit b5c20d0

Browse files
committed
Translate Name mangling example
1 parent 3b9d9bd commit b5c20d0

File tree

1 file changed

+77
-0
lines changed

1 file changed

+77
-0
lines changed

translations/README-ru.md

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3222,3 +3222,80 @@ Ellipsis
32223222
- Интересно, что хэш `float('-inf')` - "-10⁵ x π" в Python 3, тогда как в Python 2 - "-10⁵ x e".
32233223
32243224
---
3225+
3226+
3227+
### ▶ Давайте искажать
3228+
<!-- Example ID: 37146d2d-9e67-43a9-8729-3c17934b910c --->
3229+
1\.
3230+
```py
3231+
class Yo(object):
3232+
def __init__(self):
3233+
self.__honey = True
3234+
self.bro = True
3235+
```
3236+
3237+
**Результат:**
3238+
```py
3239+
>>> Yo().bro
3240+
True
3241+
>>> Yo().__honey
3242+
AttributeError: 'Yo' object has no attribute '__honey'
3243+
>>> Yo()._Yo__honey
3244+
True
3245+
```
3246+
3247+
2\.
3248+
```py
3249+
class Yo(object):
3250+
def __init__(self):
3251+
# Попробуем симметричные двойные подчеркивания в названии атрибута
3252+
self.__honey__ = True
3253+
self.bro = True
3254+
```
3255+
3256+
**Результат:**
3257+
```py
3258+
>>> Yo().bro
3259+
True
3260+
3261+
>>> Yo()._Yo__honey__
3262+
Traceback (most recent call last):
3263+
File "<stdin>", line 1, in <module>
3264+
AttributeError: 'Yo' object has no attribute '_Yo__honey__'
3265+
```
3266+
3267+
Почему обращение к `Yo()._Yo__honey` сработало?
3268+
3269+
3\.
3270+
3271+
```py
3272+
_A__variable = "Some value"
3273+
3274+
class A(object):
3275+
def some_func(self):
3276+
return __variable # переменная еще не инициализирована
3277+
```
3278+
3279+
**Результат:**
3280+
```py
3281+
>>> A().__variable
3282+
Traceback (most recent call last):
3283+
File "<stdin>", line 1, in <module>
3284+
AttributeError: 'A' object has no attribute '__variable'
3285+
3286+
>>> A().some_func()
3287+
'Some value'
3288+
```
3289+
3290+
3291+
#### 💡 Объяснение:
3292+
3293+
* [Искажение имени](https://en.wikipedia.org/wiki/Name_mangling) используется для предотвращения коллизий имен между различными пространствами имен.
3294+
* В Python интерпретатор изменяет (mangles) имена членов класса, начинающиеся с `__` (двойное подчеркивание, оно же "дундер") и не заканчивающиеся более чем одним подчеркиванием в конце, добавляя перед ними `_NameOfTheClass`.
3295+
* Таким образом, чтобы получить доступ к атрибуту `__honey` в первом фрагменте, мы должны были добавить `_Yo` спереди, что предотвратило бы конфликты с тем же атрибутом `name`, определенным в любом другом классе.
3296+
* Но почему тогда это не сработало во втором фрагменте? Потому что при манипулировании именами исключаются имена, заканчивающиеся двойным подчеркиванием.
3297+
* Третий фрагмент также является следствием манипулирования именами. Имя `__variable` в операторе `return __variable` было искажено до `_A__variable`, что также является именем переменной, которую мы объявили во внешней области видимости.
3298+
* Кроме того, если длина искаженного имени превышает 255 символов, произойдет усечение (truncation).
3299+
3300+
---
3301+
---

0 commit comments

Comments
 (0)