>>> Стиль имеет значение
PEP8 – это руководство по стилю кодирования на Python. PEP8 рекомендует, чтобы имена функций и переменных использовали буквы только в нижнем регистре и _
(подчеркивание) в качестве разделителя слов:
i
name
full_name
Использование однобуквенных переменных l
(эл), O
(оу) и I
(ай) считается злом, так как их непросто отличить от цифр 1
и 0
или друг от друга (l
и I
).
Согласно PEP8, идентификаторы в стандартной библиотеке Python могут использовать только символы ASCII. Разумно распространить это соглашение на свой код, хотя технически такого ограничения в Python 3 нет:
>>> # не нужно так делать
>>> привет = 'Hello'
>>> привет
'Hello'
>>>
>>> Статический метод
Статический метод в классе определяется с помощью декоратора staticmethod
. Это обычный метод в пространстве имен класса, при его вызове неявные аргументы не передаются.
>>> class C:
... @staticmethod
... def answer():
... return 42
...
>>> C.answer()
42
>>> C().answer()
42
Таким образом, статический метод не имеет доступа к классу (через cls
, как класс-метод) или экземпляру класса (через self
, как инстанс-метод).
>>> Стиль влияет
Согласно PEP8, имена, начинающиеся с _
(подчеркивание), предназначены для использования только внутри модуля, в котором они определены. Поэтому предложение
from module import *
такие имена не импортирует, если только они явно не включены в список импорта __all__
в модуле.
Отсюда, чтобы предотвратить импорт глобальных переменных из вашего модуля предложением from module import *
, начинайте их имена с _
или используйте __all__
для ограничения "экспортируемых" модулем имен.
>>> Соглашение, а не запрет
Пусть будет модуль:
# my.py
__all__ = ["salut"]
hello = 'Hello!'
salut = 'Salut !'
_memo = 'Use it or lose it'
Импортировав имена из модуля с помощью *
, проверим их доступность:
>>> from my import *
>>> salut
'Salut !'
>>> hello
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'hello' is not defined
>>> _memo
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name '_memo' is not defined
Итак, разработчик модуля явно объявил "экспортируемые" им имена в списке __all__
. Explicit is better than implicit, как учит Python Zen. Следуя этой же добродетели, импортировать имена из модуля нужно явно (а не злоупотреблять звездочкой):
>>> from my import _memo
>>> _memo
'Use it or lose it'
"Приватность" переменной _memo
и ее отсутствие в списке __all__
не мешают импортировать ее явно. Таким образом, и приватность переменных и спецификация публичных имен – в Python только удобные соглашения, позволяющие разработчику заявить о намерениях.
>>> Родитель один, родитель два, ...
Объектная модель Python поддерживает множественное наследование классов. В результате,
- дерево наследования превращается в граф с циклами и
- возникает возможность конфликта имен из родительских классов.
>>> class A:
... def whoami(self):
... print('A')
...
>>> class B:
... def whoami(self):
... print('B')
...
>>> class AB(A, B):
... pass
...
Вызов AB().whoami()
выведет на экран A
или B
или сломается?
>>> AB().whoami()
A
Такое поведение определяется порядком разрешения имен методов (MRO, method resolution order), принятым в Python: слева направо снизу вверх (сначала родители, потом деды, и так далее...)
>>> class BA(B, A):
... pass
...
>>> BA().whoami()
B
Список предков класса, отсортированный в порядке "удаленности", называют линеаризацией. Для класса AB
линеаризация будет [A, B, object]
. Видите цикл в графе наследования класса AB
?
Комментариев нет:
Отправить комментарий