E305 python ошибка

Functions and classes should have two blank lines after them, separating them from other functions and classes.

Anti-pattern

class User(object):
    pass
user = User()

Best practice

class User(object):
    pass


user = User()

Additional links

  • https://www.python.org/dev/peps/pep-0008/#blank-lines

Expected 2 blank lines after end of function or class

Functions and classes should have two blank lines after them, separating them from other functions and classes.

Anti-pattern

class User(object):
    pass
user = User()

Best practice

class User(object):
    pass


user = User()

Consider the following code:

def add_function(a, b):
    c = str(a) + b
    print "c is %s" % c

def add_int_function(c, d):
    e = c + d
    print "the vaule of e is %d" % e

if __name__ =="__main__":
    add_function(59906, 'kugrt5')
    add_int_function(1, 2)

It always shows me: «expected 2 blank lines ,found 1» in aadd_int_function, but not in the add_function.

When I add two spaces in front of the def add_int_function(c, d):
there is a error shows unindent does not match any outer indentation level
in the end of add_function:

enter image description here

enter image description here

TT--'s user avatar

TT—

2,9071 gold badge26 silver badges44 bronze badges

asked Oct 27, 2016 at 3:57

march_seven's user avatar

2

Just add another line between your function definitions :

1 line :

enter image description here

2 lines:

enter image description here

answered Oct 27, 2016 at 8:55

Kennet Celeste's user avatar

Kennet CelesteKennet Celeste

4,4833 gold badges24 silver badges34 bronze badges

6

This is a pretty common question within the python community. After the release of PEP 8, new formatting styles were accepted into python. One of them states that after the definition of a class or function there must be two lines separating them. As such:

    def yadayada:
     print("two lines between the functions")


    def secondyadayada:
     print("this is the proper formatting")

So, you should never do it like:

    def yadayada:
     print("two lines between the functions")

    def secondyadayada:
     print("this is the proper formatting")

Or else PyCharm will throw that error at you.

answered Jan 27, 2019 at 15:03

shreyshrey's user avatar

shreyshreyshreyshrey

5176 silver badges20 bronze badges

0

Further clarification on @kennet-celeste & @shreyshrey ‘s answers,

Each function or class defined requires 2 spaces above and 2 spaces below. Unless the function is the last item in the script, in which the expected format is one blank line as an End of File marker. So:

# some code followed by 2 blank spaces


def function1():


def function2():


def function3():

answered Feb 7, 2022 at 11:10

M_Merciless's user avatar

M_MercilessM_Merciless

3706 silver badges11 bronze badges

For people who wonders why it requires two blank lines

if you were to write in other languages it would be:

fun doSth() {
    print()
}

fun doSth1() {
    print()
}

but if you were to delete all the curly braces from the code you will see:

two blank lines between methods

fun doSth()
    print()
#
#
fun doSth1()
    print()
#

answered May 19, 2022 at 12:11

adwardwo1f's user avatar

adwardwo1fadwardwo1f

7616 silver badges18 bronze badges

Время на прочтение
7 мин

Количество просмотров 15K

Друзья, у нас для вас отличные новости. Во-первых на улице наконец-то светит солнышко, а это значит, что весна начинает полноправно вступать в свои права. Вторая новость более профильная — уже 20 марта стартует первое занятие в новом потоке по курсу «Разработчик Python», в связи с этим мы публикуем заключительную часть статьи «Знакомство с Тестированием в Python», предыдущие части которой можно прочитать здесь и здесь.

Тестирование в Нескольких Средах

До сих пор вы проводили тесты для одной версии Python с помощью виртуальной среды с определенным набором зависимостей. Но всегда может возникнуть потребность проверить работу приложения на нескольких версиях Python или нескольких версиях пакета. Tox — приложение, автоматизирующее тестирование в нескольких средах.

Установка Tox

Tox доступен на PyPl в виде пакета для установки через pip:

$ pip install tox

После установки, можно переходить к настройке Tox.

Настройка Tox Для Ваших Зависимостей

Tox настраивается через файл конфигурации в каталоге проекта. В нем содержится следующее:

  • Команда, которую нужно запустить для выполнения тестов;
  • Любые дополнительные пакеты, необходимые для выполнения;
  • Целевые версии Python, выбранные для тестирования.

Вместо того, чтобы изучать синтаксис настройки Tox, можно начать с запуска quickstart-приложения.

$ tox-quickstart

Инструмент настройки Tox задаст вам вопросы и создаст файл, похожий на следующий, в tox.ini:

[tox]
envlist = py27, py36

[testenv]
deps =

commands =
    python -m unittest discover

Прежде чем запустить Tox, убедитесь, что в папке приложения есть файл setup.py с шагами установки пакета. Если его нет, воспользуйтесь руководством по созданию setup.py.

А если ваш проект не предназначен для распространения на PyPl, можно пропустить это требование, добавив следующую строку в файл tox.ini под заголовком tox:

[tox]
envlist = py27, py36
skipsdist=True

Если вы не создаете setup.py, а в приложении есть некоторые зависимости от PyPl, понадобится уточнить их в разделе testenv. Например, Django потребует следующего:

[testenv]
deps = django

По завершении этого этапа можно запускать тесты.

Теперь можно выполнить Tox, и он создаст две виртуальные среды: одну для Python 2.7 и одну для Python 3.6. Директория Tox называется .tox/. В ней Tox выполнит -m unittest discover для каждой виртуальной среды.

Можно запустить этот процесс, вызвав Tox из командной строки:

$ tox

Tox выдаст результаты тестов для каждого окружения. При первом запуске Tox нужно время на создание виртуальных окружений, но при втором запуске все будет работать гораздо быстрее.
Результаты работы Tox довольно простые. Создаются окружения для каждой версии, устанавливаются зависимости, а затем запускаются тестовые команды.

Есть еще несколько дополнительных параметров командной строки, которые стоит запомнить.
Запуск единственного окружения, например, Python 3.6:

$ tox -e py36

Повторное создание виртуальной среды при изменении зависимости или повреждении side-packages:

$ tox -r

Запуск Tox с менее подробным выводов:

$ tox -q

Запуск Tox с более подробным выводом:

$ tox -v

Более подробно о Tox можно прочитать на сайте документации Tox.

Автоматизация Выполнения Тестов

До сих пор вы выполняли тесты вручную, запуская команду. Но существуют инструменты для автоматического выполнения тестов при внесения изменений и их коммите в репозиторий с системой контроля версий, например, Git. Инструменты для автоматизации тестирования часто называют инструментами CI/CD, что означает “Continuous Integration/Continuous Deployment” (Непрерывная Интеграция/Непрерывное Развертывание). Они могут запускать тесты, компилировать и публиковать приложения, и даже развертывать их на продакшн.
Travis CI — один из многих доступных CI сервисов.

Travis CI хорошо работает с Python, и теперь вы можете автоматизировать выполнение всех созданных тестов в облаке! Travis CI бесплатен для любых проектов с открытым исходным кодом на GitHub и GitLab и доступен за определенную плату для частных проектов.

Для начала, войдите на сайт и выполните аутентификацию с помощью ваших учетных данных GitHub или GitLab. Затем создайте файл с названием .travis.yml со следующим содержанием:

language: python
python:
  - "2.7"
  - "3.7"
install:
  - pip install -r requirements.txt
script:
  - python -m unittest discover

Эта конфигурация дает Travis CI следующие указания:

  • Тестирование для Python 2.7 и 3.7 (По желанию, можно заменить их на любые другие.)
  • Установка всех пакетов, перечисленных в requirements.txt (Можно убрать этот раздел, если у вас нет зависимостей.)
  • Запуск python -m unittest discover для запуска тестов.

После коммита и пуша этого файла, Travis CI будет запускать эти команды каждый раз, когда вы пушите в свой удаленный Git-репозиторий. Результаты можно посмотреть на их сайте.

Что Дальше

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

Введение Линтеров в Приложение

У Tox и Travis CI есть настройка тестовой команды. В этом туториале в качестве тестовой команды мы использовали python -m unittest discover.

Вы можете предоставить одну или несколько команд в этих инструментах, что позволит добавлять новые инструменты для улучшения качества приложения.

Одно из таких приложений — линтер. Он будет смотреть ваш код и оставлять комментарии. Тем самым, он может давать советы по поводу ошибок, править конечные пробелы и даже предугадывать потенциальные баги.

Чтобы узнать больше о линтерах, почитайте туториал по Качеству Кода в Python.

Пассивный Линтинг с flake8

flake8 — популярный линтер, который оставляет комментарии о стиле вашего кода в соответствии с PEP 8 спецификацией.

Установить flake8 можно с помощью pip:

$ pip install flake8

Затем можно запустить flake8 для одного файла, папки или шаблона:

$ flake8 test.py
test.py:6:1: E302 expected 2 blank lines, found 1
test.py:23:1: E305 expected 2 blank lines after class or function definition, found 1
test.py:24:20: W292 no newline at end of file

Вы увидите список ошибок и предупреждений в вашем коде, найденных flake8.
flake8 можно настраивать в командной строке или в файле конфигурации проекта. Если вы хотите игнорировать некоторые правила, например E305, показанный выше, то можете задать это в конфигурации. flake8 проверит файл .flake8 в папке проекта или файл setup.cfg. Если вы хотите использовать Tox, то можно добавить раздел настройки flake8 в tox.ini.

В этом примере игнорируются директории .git and __pycache__, а также правило E305. Кроме того, максимальная длина строки увеличивается с 80 знаков до 90. Вы, в какой-то момент, поймете, что стандартное ограничение в 79 символов на строку не подходит для тестов, в которых могут содержаться длинные названия методов, строковые литералы с тестовыми значениями и прочие длинные фрагменты данных. Обычно для тестов увеличивают длину строки до 120 символов:

[flake8]
ignore = E305
exclude = .git,__pycache__
max-line-length = 90

Кроме того, можно предоставить эти параметры в командной строке:

$ flake8 --ignore E305 --exclude .git,__pycache__ --max-line-length=90

Полный список параметров настройки можно посмотреть на Сайте Документации.
Теперь вы можете добавить flake8 к настройке CI. Для Travis CI это будет выглядеть следующим образом:

matrix:
  include:
    - python: "2.7"
      script: "flake8"

Travis прочитает конфигурацию в .flake8 и не сможет завершить сборку при наличии ошибок линтинга. Убедитесь, что вы добавили зависимость flake8 в файл requirements.txt.

Агрессивный Линтинг с Форматтером Кода

flake8 — пассивный линтер, который только рекомендует правки, вносить их в код вам придется самостоятельно. Форматтер кода — более агрессивный подход. Он меняет код автоматически в соответствии со стилями и макетами.

black — очень неумолимый форматтер. В нем нет настроек и он очень дотошный. Что делает его отличным инструментом для вставки в ваш тестовый пайплайн.

Обратите внимание: для black требуется Python версии 3.6 и выше.

Установить black можно с помощью pip:

$ pip install black

Затем, чтобы запустить из командной строки, укажите файл или директорию, которую вы хотите форматировать:

$ black test.py

Следите за Чистотой Тестового Кода

Можно заметить, что при написании тестов копипастить фрагменты кода вы будете гораздо чаще, чем при создании обычных приложений. Время от времени, тесты могут быть очень однообразными, но это совсем не повод бросить код в неаккуратном и разрозненном виде.

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

При написании тестов старайтесь следовать принципу DRY: Don’t Repeat Yourself (Не Повторяйтесь).

Тестовые фикстуры и функции — отличный способ писать код, который легко поддерживать. Кроме того, не забывайте про легкость для чтения. Подумайте о развертывании инструментов для линтинга, например, flake8 на ваш тестовый код:

$ flake8 --max-line-length=120 tests/

Тестирование для Выявления Снижения Производительности между Правками

Есть множество способов для бенчмаркинга кода в Python. В стандартной библиотеке есть модуль timeit, который планирует функции несколько раз и показывает вам распределение. В этом примере test() будет выполнен 100 раз, а затем будет дан вывод с помощью print():

def test():
    # ... your code

if __name__ == '__main__':
    import timeit
    print(timeit.timeit("test()", setup="from __main__ import test", number=100))

Если вы решите использовать pytest в качестве исполнителя тестов, обратите внимание на плагин pytest-benchmark. Он предоставляет pytest фикстуру под названием benchmark. Любой вызываемый объект может быть передан benchmark(), он залогирует время вызываемого в результатах pytest.

Установить pytest-benchmark из PyPl можно с помощью pip:

$ pip install pytest-benchmark

Затем можно добавить тест, использующий фикстуру и передающий вызываемый объект на выполнение:

def test_my_function(benchmark):
    result = benchmark(test)

Выполнение pytest выдаст вам бенчмарк-результаты:

Узнать больше можно на Сайте Документации.

Тестирование для Выявления Ошибок Безопасности

Еще один тест, который стоит запустить на вашем приложении — проверка на распространенные ошибки и уязвимости безопасности.

Установите bandit из PyPl с помощью pip:

$ pip install bandit

Затем можно передать название вашего модуля приложения с флагом -r и получить краткую информацию:

$ bandit -r my_sum
[main]  INFO    profile include tests: None
[main]  INFO    profile exclude tests: None
[main]  INFO    cli include tests: None
[main]  INFO    cli exclude tests: None
[main]  INFO    running on Python 3.5.2
Run started:2018-10-08 00:35:02.669550

Test results:
        No issues identified.

Code scanned:
        Total lines of code: 5
        Total lines skipped (#nosec): 0

Run metrics:
        Total issues (by severity):
                Undefined: 0.0
                Low: 0.0
                Medium: 0.0
                High: 0.0
        Total issues (by confidence):
                Undefined: 0.0
                Low: 0.0
                Medium: 0.0
                High: 0.0
Files skipped (0):

Как и в случае с flake8, правила флагов bandit можно настраивать, а если вы хотите игнорировать некоторые из них, можно добавить следующий фрагмент в файл setup.cfg с параметрами:

[bandit]
exclude: /test
tests: B101,B102,B301

Больше информации на сайте GitHub.

Заключение

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

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

Спасибо, что прочитали. Желаю безошибочного будущего с Python!

А для тех, кто дочитал статью, у нас еще одна отличная новость. Прямо сейчас можно успеть приобрести курс «Разработчик Python» со скидкой 10000 рублей!

Первая часть
Вторая часть

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
W = 1
B = 2
 
 
def opponent(color):
    if color == W:
        return B
    else:
        return W
 
 
def correct_coords(row, col):
    return 0 <= row < 8 and 0 <= col < 8
 
 
class Board:
    def __init__(self):
        self.color = W
        self.field = []
        for row in range(8):
            self.field.append([None] * 8)
 
        self.field[0] = [
            Rook(W), Knight(W), Bishop(W), Queen(W),
            King(W), Bishop(W), Knight(W), Rook(W)
        ]
        self.field[1] = [
            Pawn(W), Pawn(W), Pawn(W), Pawn(W),
            Pawn(W), Pawn(W), Pawn(W), Pawn(W)
        ]
        self.field[6] = [
            Pawn(B), Pawn(B), Pawn(B), Pawn(B),
            Pawn(B), Pawn(B), Pawn(B), Pawn(B)
        ]
        self.field[7] = [
            Rook(B), Knight(B), Bishop(B), Queen(B),
            King(B), Bishop(B), Knight(B), Rook(B)
        ]
 
    def current_player_color(self):
        return self.color
 
    def cell(self, row, col):
        piece = self.field[row][col]
        if piece is None:
            return '  '
        color = piece.get_color()
        c = 'w' if color == W else 'b'
        return c + piece.char()
 
    def get_piece(self, row, col):
        if correct_coords(row, col):
            return self.field[row][col]
        else:
            return None
 
    def move_piece(self, row, col, row1, col1):
        if not correct_coords(row, col) or not correct_coords(row1, col1):
            return False
        if row == row1 and col == col1:
            return False
 
        piece = self.field[row][col]
        if piece is None:
            return False
        if piece.get_color() != self.color:
            return False
        if not piece.can_move(self, row, col, row1, col1):
            return False
        self.field[row][col] = None
        self.field[row1][col1] = piece
        piece.set_position(row1, col1)
        self.color = opponent(self.color)
        return True
 
    def is_under_attack(self, row, col, color):
        for i in range(8):
            for j in range(8):
                if self.field[i][j]:
                    if self.field[i][j].get_color() ==
                            color and self.field[i][j].can_move(row, col):
                        return True
        return False
 
 
class Piece:
    def __init__(self, color):
        self.color = color
 
    def can_move(self, board, row, col, row1, col1):
        if not correct_coords(row, col) or not correct_coords(row1, col1):
            return False
        if row == row1 and col == col1:
            return False
        if board.cell(row1, col1)[1] != ' ':
            if board.get_piece(row1, col1).get_color() == self.color:
                return False
        return True
 
    def set_position(self, row, col):
        self.row, self.col = row, col
 
    def get_color(self):
        return self.color
 
 
class Pawn(Piece):
    def can_move(self, board, row, col, row1, col1):
        if not super().can_move(board, row, col, row1, col1):
            return False
        if col != col1:
            return False
 
        if self.color == W:
            direction = 1
            start_row = 1
        else:
            direction = -1
            start_row = 6
 
        if row + direction == row1:
            return True
        if (row == start_row
                and row + 2 * direction == row1
                and board.field[row + direction][col] is None):
            return True
        return False
 
    def char(self):
        return 'P'
 
 
class Rook(Piece):
    def can_move(self, board, row, col, row1, col1):
        if not super().can_move(board, row, col, row1, col1):
            return False
        if row != row1 and col != col1:
            return False
 
        step = 1 if (row1 >= row) else -1
        for r in range(row + step, row1, step):
            if not (board.get_piece(r, col) is None):
                return False
 
        step = 1 if (col1 >= col) else -1
        for c in range(col + step, col1, step):
            if not (board.get_piece(row, c) is None):
                return False
        return True
 
    def char(self):
        return 'R'
 
 
class Knight(Piece):
    def can_move(self, board, row, col, row1, col1):
        if not super().can_move(board, row, col, row1, col1):
            return False
 
        if not ((abs(row1 - row) == 2 and abs(col1 - col) == 1) or
                (abs(row1 - row) == 1 and abs(col1 - col) == 2)):
            return False
        return True
 
    def char(self):
        return 'N'
 
 
class Bishop(Piece):
    def can_move(self, board, row, col, row1, col1):
        if not super().can_move(board, row, col, row1, col1):
            return False
 
        if not abs(row1 - row) == abs(col1 - col):
            return False
 
        stepx = 1 if (col1 >= col) else -1
        stepy = 1 if (row1 >= row) else -1
        for i in range(1, abs(row1 - row)):
            if not (board.get_piece(row + i * stepy, col + i * stepx) is None):
                return False
        return True
 
    def char(self):
        return 'B'
 
 
class Queen(Piece):
    def can_move(self, board, row, col, row1, col1):
        if not super().can_move(board, row, col, row1, col1):
            return False
 
        if abs(row1 - row) == abs(col1 - col):
            stepx = 1 if (col1 >= col) else -1
            stepy = 1 if (row1 >= row) else -1
 
            for i in range(1, abs(row1 - row)):
                if not (board.get_piece(row + i * stepy, col + i * stepx) is None):
                    return False
            return True
 
        if row == row1 or col == col1:
            step = 1 if (row1 >= row) else -1
            for r in range(row + step, row1, step):
                if not (board.get_piece(r, col) is None):
                    return False
 
            step = 1 if (col1 >= col) else -1
            for c in range(col + step, col1, step):
                if not (board.get_piece(row, c) is None):
                    return False
            return True
        return False
 
    def char(self):
        return 'Q'
 
 
class King(Piece):
    def can_move(self, board, row, col, row1, col1):
        if not super().can_move(board, row, col, row1, col1):
            return False
        if abs(row - row1) > 1 or abs(col - col1) > 1:
            return False
        return True
 
    def char(self):
        return 'K'
(
    Board, Pawn, Rook, King, Knight, Bishop, Queen,
    W, B
)
 
board = Board()
board.field = [([None] * 8) for i in range(8)]
board.field[0][3] = Queen(W)
queen = board.get_piece(0, 3)
 
for row in range(7, -1, -1):
    for col in range(8):
        if queen.can_move(board, 0, 3, row, col):
            print('x', end='')
        else:
            cell = board.cell(row, col)[1]
            cell = cell if cell != ' ' else '-'
            print(cell, end='')
    print()

Понравилась статья? Поделить с друзьями:

Не пропустите эти материалы по теме:

  • Яндекс еда ошибка привязки карты
  • E1cf ошибка bmw
  • E303 python ошибка
  • E38 ошибка электролюкс
  • E1cexpress код ошибки 27

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии