ћерион Ќетворкс

8 минут

 огда мы только начинаем изучать Python, мы закладываем некоторые вредные привычки при написании кода, о которых мы можем даже не подозревать.

¬ы можете написать код, который сработает сейчас, но может не сработать в будущем, или вы можете использовать какие-то хитрые ходы вместо встроенной функции, котора€ могла бы облегчить вашу жизнь.

” большинства из нас сохранились не одна из тех вредных привычек при программировании на Python, что формируютс€ в период первых мес€цев обучени€. ќтлична€ новость в том, что вы можете с легкостью искоренить их, прочитав приведенный ниже текст.


1. »спользование import *

 аждый раз, когда нам становитс€ лень, то возникает соблазн импортировать все необходимое из модул€ с помощью from xyz import *.

Ёто не самый лучший подход по многим причинам.  от несколько из них:

  1. Ёто может оказатьс€ неэффективно: если в модуле очень много объектов, то вам придетс€ долго ждать, пока все импортируетс€.
  2. Ёто может вызвать конфликт имен переменных: когда вы используете *, то вы пон€ти€ не имеете, какие объекты вы импортируете и как они называютс€.

 ак же с этим боротьс€? »мпортируйте либо какой-то конкретный объект, либо весь модуль целиком.

# Using import *

# Bad
from math import *

print(floor(2.4))
print(ceil(2.4))
print(pi)

# Good
import math
from math import pi

print(math.floor(2.4))
print(math.ceil(2.4))
print(pi)	

2. Try/except: отсутствие указани€ исключени€ в блоке Ђexceptї

я очень долго пренебрегал этим. —ложно посчитать, сколько раз Pycharm давал мне пон€ть (этими противными подчеркивани€ми), что не нужно использовать Ђголоеї исключение. Ёто идет в разрез с рекомендаци€ми PEP8.

# Try - except

# Bad
try:
    driver.find_element(...)
except:
    print("Which exception?")

# Good
try:
    driver.find_element(...)
except NoSuchElementException:
    print("It's giving NoSuchElementException")
except ElementClickInterceptedException:
    print("It's giving ElementClickInterceptedException")	

ѕроблема Ђголыхї исключений заключаетс€ в том, что оно будет перехватывать исключени€ SystemExit и KeyboardInterrupt, что затрудн€ет прерывание программы с помощью Control-C.

¬ следующий раз, когда вы будете использовать try/except, укажите исключение в блоке except.


3. Ќе использовать Numpy дл€ математических вычислений

ќчень часто мы забываем, что в Python есть множество пакетов, которые могут значительно облегчить нашу жизнь и сделать ее более продуктивной.

ќдним из таких пакетов €вл€етс€ Numpy Ц пакет дл€ математических вычислений. Numpy может помочь вам вычисл€ть математические операции быстрее, чем циклы for.

ƒопустим, что у нас есть массив random_scores, и мы хотим получить средний балл тех, кто не сдал экзамен (score<70). “еперь попробуем решить это с помощью цикла for.

import numpy as np

random_scores = np.random.randint(1, 100, size=10000001)

# Bad (solving problem with a for loop)
count_failed = 0
sum_failed = 0
for score in random_scores:
    if score < 70:
        sum_failed += score
        count_failed += 1

print(sum_failed/count_failed)	

ј теперь давайте решим это с помощью Numpy.

# Good (solving problem using vector operations)
mean_failed = (random_scores[random_scores < 70]).mean()
print(mean_failed)	

≈сли вы запустите оба варианта, то увидите, что Numpy работает быстрее. ѕочему? ѕотому что Numpy распараллеливает наши операции.


4. Ќе закрываете ранее открытый файл

ќбычна€ практика, которую знают все, заключаетс€ в том, что каждый файл, который мы открываем с помощью Python, должен быть закрыт.

¬от почему мы используем open, write/read, close каждый раз при работе с файлами. Ёто нормально, но если методы write/read генерируют исключение, то файл закрыт не будет.

ƒл€ того, чтобы избежать данной проблемы, мы должны использовать оператор with. Ёто закроет файл, даже если есть исключение.

# Bad
f = open('dataset.txt', 'w')
f.write('new_data')
f.close()

# Good
with open('dataset.txt', 'w') as f:
    f.write('new_data')	

5. Ќесоблюдение рекомендаций PEP8

PEP8 Ц это документ, который должен прочитать каждый, кто изучает Python. ¬ нем содержатс€ руковод€щие принципы и методические рекомендации по написанию программного кода на Python (некоторые рекомендации в этой статье вз€ты именно из PEP8).

Ёто руководство может немного напугать новичков в Python.   счастью, некоторые правила PEP8 уже встроены в IDE (именно так € и узнал о правиле, касающемс€ Ђгологої исключени€).

ƒопустим, что вы используете Pycharm. ≈сли вы начнете писать код, который не соответствует рекомендаци€м –≈–8, то вы увидите эти противные подчеркивани€ как на картинке ниже.

PEP8

≈сли вы наведете курсор на подчеркивание, то увидите инструкции по исправлению.

¬ моем случае мне нужно только добавить пробелы после зап€тых и двоеточий.

# Good
my_list = [1, 2, 3, 4, 5]
my_dict = {'key1': 'value1', 'key2': 'value2'}

my_name = "Frank"	

я также изменил им€ моей переменной x на my_name. ƒл€ Pycharm это не так важно, но –≈–8 рекомендует использовать имена переменных, по которым легко пон€ть, что она обозначает.


6. Ќеправильное использование методов .keys и .values при работе со словар€ми

ƒумаю, что многие из вас знают, что делают методы .keys и .values при работе со словар€ми.

≈сли все же не знаете, то давайте посмотрим.

dict_countries = {'USA': 329.5, 'UK': 67.2, 'Canada': 38}>>>dict_countries.keys()
dict_keys(['USA', 'UK', 'Canada'])>>>dict_countries.values()
dict_values([329.5, 67.2, 38])	

ѕроблема тут заключаетс€ в том, что мы не всегда используем их должным образом.

Ќапример, мы хотим просмотреть словарь и получить ключи. ¬ы можете использовать метод .keys, но знаете ли вы, что ключи можно получить, просто перебира€ словарь? ¬ этом случае использование метода .keys будет излишним.

# Not using .keys() properly
# Bad
for key in dict_countries.keys():
    print(key)
    
# Good
for key in dict_countries:
    print(key)	

 роме того, можно придумать некоторые хитрости дл€ получени€ значений словар€, например, с помощью метода .items().

# Not using .items()
# Bad
for key in dict_countries:
    print(dict_countries[key])
    
# Good
for key, value in dict_countries.items():
    print(key)
    print(value)	

7. Ќикогда не использовать генераторы (или использовать их всегда)

√енератор предлагает более простой синтаксис при создании новой последовательности (списка, словар€ и т.д.) на основе уже определенной последовательности.

ƒопустим, мы хотим перевести все элементы в нашем списке countries в нижний регистр.

» хот€ вы могли бы это сделать просто с помощью цикла for, но также вы можете упростить работу при помощи генератора списка.

# Bad
countries = ['USA', 'UK', 'Canada']

lower_case = []
for country in countries:
    lower_case.append(country.lower())

# Good (but don't overuse it!)
lower_case = [country.lower() for country in countries]	

√енераторы Ц это очень полезно, но не злоупотребл€йте ими! ѕомните правило ƒзен Python: Ђѕростое лучше, чем сложноеї.


8. »спользование range(len())

ќдни из первых функций, которые мы изучили будучи новичками Ц это range и len, поэтому не удивительно, почему многие люди имеют дурную привычку писать range(len()) при переборе списков.

ƒопустим у нас есть два списка: countries и populations. ≈сли мы хотим пройтись по обоим спискам одновременно, то, веро€тнее всего, вы воспользуетесь range(len()).

# Using range(len())
countries = ['USA', 'UK', 'Canada']
populations = [329.5, 67.2, 38]

# Bad
for i in range(len(countries)):
    country = countries[i]
    population = populations[i]
    print(f'{country} has a population of {population} million people')

» хот€ это в принципе выполн€ет свою работу, вы все равно можете упростить задачу, воспользовавшись enumerate (или, что еще лучше, воспользовавшись функцией zip дл€ сопр€жени€ элементов из обоих списков).

# OK
for i, country in enumerate(countries):
    population = populations[i]
    print(f'{country} has a population of {population} million people')

# Much Better
for country, population in zip(countries, populations):
    print(f'{country} has a population of {population} million people')	

9. ‘орматирование с помощью оператора +

¬еро€тно, одна из первых вещей, которую мы изучаем в Python, - это то, как соедин€ть строки с помощью оператора +.

Ёто полезный, но не самый эффективный способ соединени€ строк в Python. ѕомимо этого, это не очень красиво Ц чем больше строк вам нужно соединить, тем больше операторов + вы будете использовать.

¬место этого вы можете воспользоватьс€ f-строкой.

# Formatting with + operator
# Bad
name = input("Introduce Name: ")
print("Good Morning, " + name + "!")

# Good
name = input("Introduce Name: ")
print(f'Good Morning, {name}')	

ѕреимуществом f-строк в том, что они полезны не только дл€ конкатенации, но и дл€ других целей.


10. »спользование измен€емых значений в качестве значений по умолчанию

≈сли вы включите измен€емое значение (например, список) в качестве параметра функции по умолчанию, то увидите нечто неожиданное.

# Bad
def my_function(i, my_list=[]):
    my_list.append(i)
    return my_list>>> my_function(1)
[1]
>>> my_function(2)
[1, 2]
>>> my_function(3)
[1, 2, 3]	

¬ приведенном выше коде каждый раз, когда мы вызываем функцию my_function, список my_list сохран€ет значени€ из предыдущих вызовов (а мы, скорее всего, хотим инициировать пустой список при каждом вызове функции).

„тобы избежать такой проблемы, мы должны установить этот параметр my_list равным None и добавить условие if как показано ниже.

# Good
def my_function(i, my_list=None):
    if my_list is None: 
        my_list = []
    my_list.append(i)
    return my_list>>> my_function(1)
[1]
>>> my_function(2)
[2]
>>> my_function(3)
[3]	

—кидки 50% в Merion Academy

¬ыбрать курс