18 способов написать лучший Python
Не используйте .append()
повторно, используйте .extend()
1. Используйте x.extend(…) вместо многократного вызова x.append()
При добавлении нескольких значений в список вы можете использовать метод .extend()
для добавления итерации в конец существующего списка. Таким образом, вам не нужно вызывать .append()
для каждого элемента:
Плохо
nums = [1, 2, 3]
nums.append(4)
nums.append(5)
nums.append(6)
Хорошо
nums = [1, 2, 3]
nums.extend((4, 5, 6))
2. print("") можно упростить до print()
Плохо
print("")
Хорошо
print()
3. isinstance()/issubclass() может принимать несколько аргументов
isinstance()
и issubclass()
принимают аргументы кортежа, поэтому вместо того, чтобы вызывать их несколько раз для одного и того же объекта, вы можете проверить их все сразу.
Плохо
if isinstance(num, float) or isinstance(num, int):
pass
Хорошо
if isinstance(num, (float, int)):
pass
4. Когда вы хотите записать список строк в файл, не вызывайте .write() для каждой строки, вместо этого используйте .writelines()
Плохо
lines = ["line 1", "line 2", "line 3"]
with open("file") as f:
for line in lines:
f.write(line)
Хорошо
lines = ["line 1", "line 2", "line 3"]
with open("file") as f:
f.writelines(lines)
Если у вас есть более сложное выражение, чем просто lines
, вам может понадобиться вместо этого использовать понимание списка. Например:
f.writelines(f"{line}\\n" for line in lines)
5. Используйте подавлять() вместо try/except и пропускайте
Часто вы хотите обработать исключение и просто игнорировать его. Можно сделать это try/except
блоком, используя один pass
в except
блоке, но есть более простой и лаконичный способ, используя suppress()
метод из contextlib
.
Плохо
try:
f()
except FileNotFoundError:
pass
Хорошо
with suppress(FileNotFoundError):
f()
6. Используйте цепочку сравнения для проверки равенства нескольких объектов.
При проверке того, что несколько объектов равны друг другу, не используйте and
выражение. Вместо этого используйте цепочку сравнения, например:
Плохо
if x == y and x == z:
pass
Хорошо
if x == y == z:
pass
7. При сравнении значения с несколькими возможными вариантами используйте «in» вместо нескольких проверок «or».
Плохо
if x == “abc” or x == “def”:
pass
Хорошо
if x in (“abc”, “def”):
pass
8. Иногда встроенные операторы «if» можно упростить до одного выражения «or».
Плохо
z = x if x else y
Хорошо
z = x or y
9. Используйте .with_suffix() для изменения расширения файла, а не для манипулирования строкой.
Распространенной операцией является изменение расширения файла. Если у вас есть существующий Path
объект, вам не нужно преобразовывать его в строку, нарезать его и добавлять новое расширение. Вместо этого используйте with_suffix()
функцию:
Плохо
new_filepath = str(Path("file.txt"))[:4] + ".md"
Хорошо
new_filepath = Path("file.txt").with_suffix(".md")
10. Вам не всегда нужно использовать open, чтобы записать что-то в файл
Когда вы просто хотите сохранить некоторое содержимое в файл, использование with
блока немного излишне. Вместо этого вы можете использовать функцию pathlib write_text()
:
Плохо
with open(filename, "w") as f:
f.write("hello world")
Хорошо
Path(filename).write_text("hello world")
11. Более короткий способ проверить наличие ключа в словаре
Если вы хотите только проверить, существует ли ключ в словаре, вам не нужно вводить сначала .keys()
, просто используйте in
сам словарь:
Плохо
d = {"key": "value"}
if "key" in d.keys():
…
Хорошо
d = {"key": "value"}
if "key" in d:
…
12. Вам не нужно использовать «len()», чтобы проверить, пуст ли контейнер.
Не проверяйте длину контейнера, чтобы определить, пуст он или нет, вместо этого используйте проверку достоверности:
Плохо
name = "bob"
if len(name) == 0:
pass
nums = [1, 2, 3]
if len(nums) >= 1:
pass
Хорошо
name = "bob"
if not name:
pass
nums = [1, 2, 3]
if nums:
pass
13. Более быстрый способ инициализации list и dict
Использование list
и dict
без каких-либо аргументов медленнее, а не Pythonic. Используйте []
и {}
вместо:
Плохо
nums = list()
books = dict()
Хорошо
nums = []
books = {}
Из приведенных выше фрагментов видно, что инициализация list с помощью []
и dict с помощью {}
выполняется быстрее, чем инициализация их объектов.
14. Используйте «operator» вместо lambda-выражений
Не пишите lambda-функции для переноса встроенных операторов, operator
вместо этого используйте модуль:
Плохо
from functools import reduce
nums = [1, 2, 3]
print(reduce(lambda x, y: x + y, nums)) # 6
Хорошо
from functools import reduce
from operator import add
nums = [1, 2, 3]
print(reduce(add, nums)) # 6
15. Хороший способ обмена
Вам не нужно использовать временную переменную для замены двух переменных, вместо этого вы можете использовать распаковку кортежа:
Плохо
temp = x
x = y
y = tmp
Хорошо
x, y = y, x
16. Лучший способ манипулировать табуляцией в строках
Вместо использования replace("\\t", " " * 8)
вы можете использовать expandtabs()
метод. Оно более лаконичное и описательное. Это также позволяет использовать необязательный параметр для указания ширины вкладки.
Плохо
spaces_8 = "hello\\tworld".replace("\\t", " " * 8)
spaces_4 = "hello\\tworld".replace("\\t", " ")
Хорошо
spaces_8 = "hello\\tworld".expandtabs()
spaces_4 = "hello\\tworld".expandtabs(4)
17. Лучший способ печатать двоичные, восьмеричные и шестнадцатеричные числа
Функции bin()
, oct()
и hex()
возвращают строковое представление числа, но с добавленным префиксом. Если вам не нужен префикс, у вас может возникнуть соблазн просто отрезать его, но использование f-строки даст вам больше гибкости:
Плохо
print(bin(1337)[2:])
Хорошо
print(f"{1337:b}")
18. Лучший способ проверить несколько вещей наstartswith() and endswith()
startswith()
tar endswith()
и оба принимают кортеж, поэтому вместо того, чтобы startswith()
несколько раз вызывать одну и ту же строку, вы можете проверить их все сразу:
Плохо
name = “bob”
if name.startswith(“b”) or name.startswith(“B”):
pass
Хорошо
name = “bob”
if name.startswith((“b”, “B”)):
pass
Здесь приведены несколько примеров, как вам сэкономить ваше время и сделать работу более организованной.