Unused import statement pycharm как исправить

Given this scenario: b.py: import A # A is unused here c.py: from b import A # A is used here PyCharm complains in b.py that import A is an unused import and Optimize imports deletes it, breaking

Given this scenario:

b.py:

import A
# A is unused here

c.py:

from b import A
# A is used here

PyCharm complains in b.py that import A is an unused import and Optimize imports deletes it, breaking import in c.py.

I know these chained imports are not a good practice (although you may use it to implement a facade module), but is it me or is it a PyCharm fail?

bad_coder's user avatar

bad_coder

10.4k20 gold badges43 silver badges65 bronze badges

asked Jan 15, 2014 at 13:55

Mihnea Simian's user avatar

Mihnea SimianMihnea Simian

1,0931 gold badge7 silver badges13 bronze badges

3

You can actually use the PyUnresolvedReferences marker to deactivate the inspection for your import statement:

# noinspection PyUnresolvedReferences
import A

Reference: PyCharm bug PY-2240

answered Jan 30, 2014 at 22:44

benselme's user avatar

3

As far as I can tell this behaviour is not handled as an inspection or some other configurable option, which means there is no #noinspection UnusedImport (or equivalent) that can be placed before the imports.

If you don’t want to define an unused block where you use those variables there’s an other simple and probably better way to achieve what you want:

#b.py code
import A

# [...] your code


__all__ = ['A', ...]  # *all* the names you want to export

PyCharm is smart enough to look at __all__ and avoid removing A as unused import.
However there’s a limitation that __all__ must be a simple list literal. You cannot do things like:

__all__ = ['A'] + [name for name in iterable if condition(name)]

Not even:

x = 'b'
__all__ = ['A', x]

Defining __all__ is a best-practice to make your module *-import safe anyway, so is something you should already do.

answered Jan 15, 2014 at 16:56

Bakuriu's user avatar

BakuriuBakuriu

96.3k21 gold badges192 silver badges223 bronze badges

0

from C import A, B
_ = (A, B); del _

Works for me. I don’t like

# noinspection PyUnresolvedReferences

as it would give false negatives in case A cannot be imported. And

__all__ = ['A', 'B', ...]

is cryptic and is not convenient for refactoring.

answered Aug 7, 2019 at 7:16

Peter Zagubisalo's user avatar

When you reference a class that has not been imported, PyCharm helps you locate this file and add it to the list of imports. You can import a single class or an entire package, depending on your settings.

The import statement is added to the imports section, but the caret does not move from the current position, and your current editing session does not suspend. This feature is known as the Import Assistant. Using Import Assistant is the preferred way to handle imports in PyCharm because import optimizations are not supported via command line.

The same possibility applies to XML files. When you type a tag with an unbound namespace, the import assistant suggests creating a namespace and offers a list of appropriate choices.

Automatically add import statements

You can configure the IDE to automatically add import statements if there are no options to choose from.

  1. Press Ctrl+Alt+S to open the IDE settings and select .

  2. In the Python section, configure automatic imports:

    • Select Show import popup to automatically display an import popup when tying the name of a class that lacks an import statement.

    • Select one of the Preferred import style options to define the way an import statement to be generated.

When tooltips are disabled, unresolved references are underlined and marked with the red bulb icon the Quick-fix button. To view the list of suggestions, click this icon (or press Alt+Enter) and select Import class.

Disable all tooltips

  • Hover the mouse over the inspection widget in the top-right corner of the editor, click More, and disable the Show Auto-Import Tooltip option.

Disable auto import

If you want to completely disable auto-import, make sure that:

  • All import tooltips are disabled.

  • The automatic insertion of import statements is disabled.

Optimize imports

The Optimize Imports feature helps you remove unused imports and organize import statements in the current file or in all files in a directory at once according to the rules specified in .

Optimize all imports

  1. Select a file or a directory in the Project tool window ().

  2. Do any of the following:

    • From the main menu, select (or press Ctrl+Alt+O).

    • From the context menu, select Optimize Imports.

  3. (If you’ve selected a directory) Choose whether you want to optimize imports in all files in the directory, or only in locally modified files (if your project is under version control), and click Run.

Optimize imports in a single file

  1. Place the caret at the import statement and press Alt+Enter or use the the Intention action button icon.

  2. Select Optimize imports.

Remove use statement

Optimize imports when committing changes to Git

If your project is under version control, you can instruct PyCharm to optimize imports in modified files before committing them to VCS.

  1. Press Ctrl+K or select from the main menu.

  2. Click Show Commit Options and in the Before commit area, select the Optimize imports checkbox.

Automatically optimize imports on save

You can configure the IDE to optimize imports in modified files automatically when your changes are saved.

  1. Press Ctrl+Alt+S to open the IDE settings and select .

  2. Enable the Optimize imports option.

    Additionally, from the All file types list, select the types of files in which you want to optimize imports.

  3. Apply the changes and close the dialog.

Optimize imports when reformatting a file

You can tell PyCharm to optimize imports in a file every time it is reformatted.

  • Open the file in the editor, press Ctrl+Alt+Shift+L, and make sure the Optimize imports checkbox is selected in the Reformat File dialog that opens.

    Reformat file dialog

After that every time you press Ctrl+Alt+L in this project, PyCharm will optimize its imports automatically.

Creating imports on the fly

Import packages on-the-fly

  1. Start typing a name in the editor. If the name references a class that has not been imported, the following prompt appears:

    the Import popup

    The unresolved references will be underlined, and you will have to invoke intention action Add import explicitly.

  2. PressAlt+Enter. If there are multiple choices, select the desired import from the list.

    choose a class to import

You can define your preferred import style for Python code by using the following options available on the Auto Import page of the project settings ():

from <module> import <name>

import <module>.<name>

the from <module> import <name> style the import <module>.<name> style

Toggling relative and absolute imports

PyCharm helps you organize relative and absolute imports within a source root. With the specific intention, you can convert absolute imports into relative and relative imports into absolute.

Converting an absolute import into relative

If your code contains any relative import statement, PyCharm will add relative imports when fixing the missing imports.

Fixing a missing import with the relative import statement

Note that relative imports work only within the current source root: you cannot relatively import a package from another source root.

The intentions prompting you to convert imports are enabled by default. To disable them, open project Settings (Ctrl+Alt+S), select , and deselect the Convert absolute import to relative and Convert relative import to absolute.

Intentions for converting imports

When you complete a ES6 symbol or a CommonJS module, PyCharm either decides on the style of the import statement itself or displays a popup where you can choose the style you need. Learn more from Auto-import in JavaScript.

Adding import statements on code completion

PyCharm automatically adds an import statement when you refer any module member or package in the Python code and invoke code completion. Auto-import on code completion is also applied to some popular package name aliases, such as np for numpy or pd for pandas.

Auto-import on code completion

PyCharm also adds import statements when you complete exported JavaScript or TypeScript symbols.

Add ES6 imports on code completion

Configure auto-import on completion

You can disable auto-import on completion and use quick-fixes instead:

Add ES6 imports on code completion

  1. In the Settings dialog (Ctrl+Alt+S), go to .

  2. On the Auto Import page that opens, use the checkboxes in the TypeScript/JavaScript area to enable or disable import generation on code completion.

Ignoring missing import statements

If you use a module in your code that doesn’t have any corresponding stub, PyCharm might show a missing statement error. To suppress this error message, use the # type: ignore comment:

Ignore a missing import statement

Last modified: 11 January 2023

Given this scenario:

b.py:

import A
# A is unused here

c.py:

from b import A
# A is used here

PyCharm complains in b.py that import A is an unused import and Optimize imports deletes it, breaking import in c.py.

I know these chained imports are not a good practice (although you may use it to implement a facade module), but is it me or is it a PyCharm fail?

bad_coder's user avatar

bad_coder

10.4k20 gold badges43 silver badges65 bronze badges

asked Jan 15, 2014 at 13:55

Mihnea Simian's user avatar

Mihnea SimianMihnea Simian

1,0931 gold badge7 silver badges13 bronze badges

3

You can actually use the PyUnresolvedReferences marker to deactivate the inspection for your import statement:

# noinspection PyUnresolvedReferences
import A

Reference: PyCharm bug PY-2240

answered Jan 30, 2014 at 22:44

benselme's user avatar

3

As far as I can tell this behaviour is not handled as an inspection or some other configurable option, which means there is no #noinspection UnusedImport (or equivalent) that can be placed before the imports.

If you don’t want to define an unused block where you use those variables there’s an other simple and probably better way to achieve what you want:

#b.py code
import A

# [...] your code


__all__ = ['A', ...]  # *all* the names you want to export

PyCharm is smart enough to look at __all__ and avoid removing A as unused import.
However there’s a limitation that __all__ must be a simple list literal. You cannot do things like:

__all__ = ['A'] + [name for name in iterable if condition(name)]

Not even:

x = 'b'
__all__ = ['A', x]

Defining __all__ is a best-practice to make your module *-import safe anyway, so is something you should already do.

answered Jan 15, 2014 at 16:56

Bakuriu's user avatar

BakuriuBakuriu

96.3k21 gold badges192 silver badges223 bronze badges

0

from C import A, B
_ = (A, B); del _

Works for me. I don’t like

# noinspection PyUnresolvedReferences

as it would give false negatives in case A cannot be imported. And

__all__ = ['A', 'B', ...]

is cryptic and is not convenient for refactoring.

answered Aug 7, 2019 at 7:16

Peter Zagubisalo's user avatar

@SM-Fahim

Hello sir.
I was trying to build a project where I need to import wikipedia module. I installed it with «pip install wikipedia». Then I checked the settings in Pycharm and added the module in the existing list of modules. But whenever I try to import it with «import wikipedia», the line gets faded saying «unused import statement». And thus unable to import the module in Pycharm. But the statement works in python IDLE. I tried troubleshoots from google and stack overflow, but nothing solved my problem. Now looking for your help.

Looking forward to hearing from you.

@DevangSharma

It shows the message to make you aware that you haven’t used any function of this module. At the instant you call any method from this module you’ll see it’s not faded anymore.
It’s just there to aware you so that you don’t import unnecessary files, it’s not an error.

@Seven719

It shows the message to make you aware that you haven’t used any function of this module. At the instant you call any method from this module you’ll see it’s not faded anymore.
It’s just there to aware you so that you don’t import unnecessary files, it’s not an error.

import discord
from discord.ext import commands

client = commands.Bot(command_prefix = ‘.’)

@client.event
async def on_ready():
print(«Bot is ready»)

client.run(‘Token’)

The thing is that I have nothing to use it for this is the whole thing and I can’t run it because of import when the guy did it there was no problem no import error no nothing everything is exactly the same as his code and dk what I should do. If you could help me I would apreaciate it a lot.

@Unown-Sapphire

It shows the message to make you aware that you haven’t used any function of this module. At the instant you call any method from this module you’ll see it’s not faded anymore.
It’s just there to aware you so that you don’t import unnecessary files, it’s not an error.

import discord
from discord.ext import commands

client = commands.Bot(command_prefix = ‘.’)

@client.event
async def on_ready():
print(«Bot is ready»)

client.run(‘Token’)

The thing is that I have nothing to use it for this is the whole thing and I can’t run it because of import when the guy did it there was no problem no import error no nothing everything is exactly the same as his code and dk what I should do. If you could help me I would apreaciate it a lot.

The same thing is also happening to me, when I run the scripts they dont work itll just say Unused import statement ‘import discord’ and wont run my bot…

@lucasszampieri

I am having the same problem, can someone help me pls

@lucasszampieri

Why did you closed man, do you know how to solve the problem?

@cnbhdr

I’m having trouble with the same problem, is there anybody who dealt with it?

@lucasszampieri

I’m having trouble with the same problem, is there anybody who dealt with it?

I solved it, send your code so I can see it

#База знаний

  • 25 май 2021

  • 15

Чтобы код оставался понятным, в нём регулярно надо убираться. Рассказываем, что и где прибирать.

Марина Демидова

Программист, консультант, специалист по документированию. Легко и доступно рассказывает о сложных вещах в программировании и дизайне.

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

Чтобы не допустить этого, при разработке периодически проводят рефакторинг — вносят изменения, которые делают код понятнее, но не меняют его функциональность.

Важно! Рефакторинг более эффективен и безопасен, когда пошаговые изменения проверяются запусками тестов.

Если вы только-только столкнулись с рефакторингом — сперва прочтите эту статью.

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

Удаляйте закомментированные куски кода. Они сбивают с толку разработчиков, которые работают с исходниками после вас.

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

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

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

Не забудьте удалить из кода соответствующие команды импорта — обычно редакторы их подсвечивают. Так, в IDE PyCharm текст команды становится бледным и при компиляции выдаётся предупреждение «Unused import statement…».

Это такие переменные, которые создаются, но нигде не применяются. Они могут остаться после исправления кода или по окончании рефакторинга. Их тоже нужно убирать.

Найти эти переменные легко — редакторы их подсвечивают, а при компиляции выдаётся предупреждение: «Variable is not used».

Например:

Здесь PyCharm выделяет серым и ненужный модуль os, и неиспользуемые переменные unused1 и unused2.

Проводя рефакторинг, важно оформить код так, чтобы его было удобно читать.

Создатель языка Python Гвидо ван Россум сказал: «Код читают гораздо чаще, чем пишут».

Действительно, вы написали кусок кода за раз, но, когда он станет частью проекта, его придётся перечитывать снова и снова — вспоминая, что он делает и почему так написан. Это придётся делать не только вам, но и вашим коллегам. Поэтому важно сделать код удобочитаемым — для всех.

Гвидо ван Россум считал удобочитаемость одним из важнейших принципов языка Python. Поэтому вместе с соратниками разработал свод рекомендаций по оформлению кода — PEP 8. Рассмотрим некоторые из них подробнее.

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

Например, имя переменной в выражении sc += 1 нам мало о чём говорит.

А если изменить его на score, то станет ясно, что речь идёт о счёте.

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

  • имена могут состоять только из цифр, букв и знаков подчёркивания;
  • имя не может начинаться с цифры.

PEP 8 предписывает задавать имена определённым образом:

  • Имена функций и модулей пишутся строчными буквами. Они могут состоять из одного или нескольких слов, которые разделяются подчёркиванием (например: function, my_function).
  • Имена переменных тоже задаются в нижнем регистре. Они могут состоять из одной буквы, слова или нескольких слов. Слова в составе имени тоже разделяются подчёркиванием: x, variable, my_var.
  • Название константы задаётся символом, словом или несколькими словами в верхнем регистре. Слова в составе имени разделяются знаком подчёркивания.

    Например:

    C, CONST, MY_CONST.

  • Имена классов состоят из одного (Class) или нескольких слов (MyClass) без разделителей.

    Во втором случае, как вы заметили, каждое слово начинается с прописной буквы. Такой стиль называется CamelCase («верблюжий стиль»).

  • Имена модулей задаются в нижнем регистре. Они не должны быть длинными. Знак подчёркивания уместен, если с ним имя модуля читабельнее, а его назначение понятнее.

    Например:

    pyclbr, py_compile.

    PEP 8 описывает и принципы оформления кода:

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

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

    Здесь линтер flake8 в PyCham выдаёт предупреждения о лишних пробелах внутри скобок и перед ними.

    Для разных языков программирования есть свои линтеры. Например, для HTML — Beautify, для JavaScript — JSLint и так далее.

    Популярные линтеры для Python:

    • Pycodestyle,
    • Pyflakes,
    • Pylint,
    • Flake8.

    Все они легко интегрируются в среды разработки. А самым умным считается pylint. Он проверяет:

    • все ли подключённые модули используются в программе;
    • есть ли лишние переменные;
    • не превышает ли длина строк 79 символов;
    • правильно ли заданы имена;
    • верно ли используются аргументы;
    • есть ли синтаксические ошибки;
    • как используются типы данных
    • и многое другое.

    Обнаруженные ошибки можно исправить вручную или с помощью утилит для форматирования кода — форматтеров, которые совместимы с IDE PyCharm или Visual Studio.

    Популярные форматтеры:

    • Autopep8,
    • YAPF,
    • Black.

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

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

    А ещё повторами часто грешат начинающие программисты. Они видят в проекте почти такой же код, как нужен им, и копируют его в другое место, немного изменив. Это приводит к проблемам:

    • Возникают куски одинакового текста, различающиеся лишь некоторыми строками или символами — и не сразу понятно какими. Это затрудняет понимание программы.
    • Текст программы раздувается, в нём труднее разобраться.
    • Когда нужно менять функциональность, за которую отвечает дублирующийся код, изменения приходится вносить сразу во много мест программы. Это чревато ошибками.

    Чтобы избавиться от дублирования, применяют приём рефакторинга «извлечение метода»: дублирующийся участок выносят в отдельный метод или функцию и везде заменяют вызовом этого метода/функции.

    Рассмотрим на примере:

    while True :
     a1 = int(input( "Введите цену товара: "))
     if a1 < 0 :
       print ("Значение не должно быть отрицательным!")
     else :
       break
    
    while True :
     a2 = int(input("Введите количество товара: "))
     if a2 < 0 :
       print ("Значение не должно быть отрицательным!")
     else :
       break
    
    a3 = a1 * a2
    print("Стоимость товара: ", a3)

    Этот код явно нуждается в рефакторинге. И вот почему:

    • два блока выполняют практически одинаковые действия;
    • названия переменных a1, a2, a3 не говорят об их предназначении.

    Мы видим в коде два блока, которые отличаются только сообщениями пользователю: «Введите цену товара: » и «Введите количество товара: ».

    Такое дублирование — это плохо:

    • Например, поменялись бизнес-правила: нас больше не интересуют товары с нулевой стоимостью. И нужно поставить условие: количество и цена должны быть больше нуля. Нам придётся вносить изменения в оба блока кода.
    • Или мы захотим, скажем, добавить в расчёт стоимости скидку/наценку. Тогда нам придётся создать ещё один похожий блок с новым сообщением: «Введите процент скидки (или наценки) на товар: ». А потом ещё один и ещё. Код быстро разрастётся.

    Чтобы упростить код, преобразуем цикл while в функцию, а сообщения для пользователя будем передавать в неё как аргументы. Назовём функцию input_value() («ввод значения»), добавим в неё команду return a1 и уберём break.

    Вот что у нас выйдет:

    def input_value() :
      while True :
         a1 = int (input("Введите цену товара: "))
         if a1 < 0 :
             print ("Значение не должно быть отрицательным!")
         else :
             return a1

    Чтобы сообщать пользователю, что вводить (цену, количество товара и так далее), вместо приглашения «Введите цену товара: » добавим параметр функции и назовём его prompt («подсказка»).

    Вот что получится:

    def input_value(prompt):
      while True:
         a1 = int(input(prompt))
         if a1 < 0 :
             print ("Значение не должно быть отрицательным!")
         else :
             return a1

    Теперь заменим одинаковые блоки кода вызовами функции с соответствующими значениями параметра. Сразу же дадим переменным новые, осмысленные имена: value, price, quantity, cost.

    Исправленный код будет выглядеть так:

    def input_value(prompt):
      while True:
         value = int( input( prompt ) )
         if value < 0 :
             print ("Значение не должно быть отрицательным!")
         else :
             return value
    
    price = input_value("Введите цену товара: ")
    quantity = input_value("Введите количество товара: ")
    cost = price * quantity
    print("Стоимость товара: ", cost)

    Переменная cost не используется в дальнейших вычислениях: она всего лишь хранит результат подсчёта стоимости товара для передачи его в качестве аргумента функции print().

    Поэтому переменную cost можно смело убирать, а в print () передавать выражение price * quantity. Это сократит код, улучшит читабельность и уменьшит используемые ресурсы:

    def input_value(prompt):
      while True:
         value = int( input( prompt ) )
         if value < 0 :
             print ("Значение не должно быть отрицательным!")
         else :
             return value
    
    price = input_value ("Введите цену товара: ")
    quantity = input_value ("Введите количество товара: ")
    print ("Стоимость товара: ", price * quantity)

    Важно! Иногда временные переменные вовсе не бесполезны. Например, когда они служат для кэширования — хранят результат затратной, ресурсоёмкой или длительной операции, который при работе программы используется несколько раз.

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

    В результате рефакторинга:

    • мы убрали дублирующийся код,
    • дали переменным осмысленные имена,
    • вынесли ввод и проверку значений в отдельную функцию.

    Программа стала короче, нагляднее и вдобавок универсальнее. Например, теперь легко добавить скидку в расчёт стоимости товара:

    def input_value(prompt):
      while True:
         value = int( input( prompt ) )
         if value < 0 :
             print ("Значение не должно быть отрицательным!")
         else :
             return value
    
    price = input_value ("Введите цену товара: ")
    quantity = input_value ("Введите количество товара: ")
    discount = input_value ("Введите процент скидки: ")
    print ("Стоимость товара: ", price * quantity * (1 - discount/100))

    Рефакторинг не ограничивается чисткой кода и улучшением его структуры. Python — язык гибкий, одну и ту же операцию позволяет реализовать по-разному.

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

    Рассмотрим несколько простых приёмов рефакторинга, которые позволяют уменьшить объём кода.

    Для создания списков, словарей и множеств в языке Python часто применяют генераторы. Один из практикуемых приёмов рефакторинга — заменить таким генератором цикл for. Код сокращается, становится нагляднее, к тому же работает быстрее.

    Пример первый

    Есть список из нескольких чисел. Нам нужно получить список квадратов этих чисел.

    Реализация с использованием цикла:

    spisok = [1, 25, 44, 213, 14, 27, 56, 8]
    square_spisok = []
    for item in spisok:
       square_spisok.append(item**2)
    print(square_spisok)
    
    --OUTPUT>
    [1, 625, 1936, 45369, 196, 729, 3136, 64]
    

    После рефакторинга с переходом к генератору:

    spisok = [1, 25, 44, 213, 14, 27, 56, 8]
    square_spisok = [item**2 for item in spisok]
    print(square_spisok)
    
    --OUTPUT>
    [1, 625, 1936, 45369, 196, 729, 3136, 64]
    

    Пример второй

    Вычисление суммы двух матриц. С циклами реализация выглядит так:

    a = [[1, 2, 3], [11,12,13], [21,22,23], [31,32,33]]
    b = [[41, 42, 43], [51,52,53], [61,62,63], [71,72,73]]
    summa_a_b = [[0,0,0], [0,0,0], [0,0,0], [0,0,0]]
    for i in range(len(a)):
       for j in range(len(a[0])):
           summa_a_b[i][j] = a[i][j] + b[i][j]
    
    print(summa_a_b)
    
    --OUTPUT>
    [[42, 44, 46], [62, 64, 66], [82, 84, 86], [102, 104, 106]]
    

    Заменим цикл генератором списка:

    a = [[1, 2, 3], [11,12,13], [21,22,23], [31,32,33]]
    b = [[41, 42, 43], [51,52,53], [61,62,63], [71,72,73]]
    summa_a_b = [[a[i][j] + b[i][j] for j in range(len(a[0]))]
                for i in range(len(a))]
    
    print(summa_a_b)
    
    --OUTPUT>
    [[42, 44, 46], [62, 64, 66], [82, 84, 86], [102, 104, 106]]
    

    После рефакторинга код стал короче.

    Почти в каждой программе приходится совершать операции над всеми элементами контейнерных типов данных: списков, словарей, кортежей.

    Иногда для этого создают переменную-счётчик и с её помощью перебирают элементы в цикле for, например:

    spisok = [154,127,98,89,77,55,32,14]
    for i in range(len(spisok)):
       print(i + 1, spisok[i])
    
    --OUTPUT>
    1 154
    2 127
    3 98
    4 89
    5 77
    6 55
    7 32
    8 14
    

    Получается, что программа перебирает не элементы списка, а значения переменной i, и каждый раз ищет нужный элемент. В сложных циклах это может привести к ошибкам. Кроме того, чтобы вывести на печать нумерованный список, в функции print() приходится прибавлять единицу к переменной i.

    Можно улучшить код — использовать функцию enumerate(), которая перебирает элементы контейнера без промежуточной переменной. У этой функции два аргумента: переменная контейнерного типа (spisok) и начальное значение счёта (переменная i). Зададим второму аргументу значение 1, чтобы счёт начинался с единицы.

    После рефакторинга код будет выглядеть так:

    spisok = [154,127,98,89,77]
    for i, spisok in enumerate(spisok, 1):
       print(i, spisok)
    
    --OUTPUT>
    1 154
    2 127
    3 98
    4 89
    5 77
    

    Если переменная принимает разные значения в зависимости от того, выполняется или нет какое-то условие, то условный оператор if…else можно заменить тернарным выражением.

    Рассмотрим пример:

    def even_odd(number):
       if number % 2 == 0:
           state = "Even"
       else:
           state = "Odd"
       return state
    print(even_odd(128))

    Заменим условие тернарным выражением:

    def even_odd(number):
       return "Even" if number % 2 == 0 else "Odd"

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

    Например:

    def f_if_else(x,y):
       if (x==1):
           if(y==2):
               return 1
           else:
               return 2
       else:
           if(y==3):
                return 3
           else:
                return 4

    Если в функции выше заменить условное выражение тернарным оператором, то в результате получим:

    def f_nested_if_else(x,y):
       return ((1) if (y == 2) else (2)) if (x == 1) else ((3) if (y == 3) else (4))

    Код стал короче, но разобраться в нём теперь намного сложнее.

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

    Пользоваться этой возможностью надо аккуратно — не усложнять понимание программы. Чтобы не запутаться, в одну строку объявляют переменные, которые связаны по смыслу.

    Пример первый

    name1 = 'Аня'
    name2 = 'Катя'
    name3 = 'Антон'
    name4 = 'Света'

    Эти переменные можно объявить в одной строке. И код станет короче:

    name1,name2,name3,name4 = 'Аня', 'Катя', 'Антон', 'Света'
    
    

    Пример второй

    Иногда переменным нужно присвоить диапазон значений:

    one = 1
    two = 2
    three = 3
    four = 4
    print(' one is',one,'n', 'two is', two, 'n', 'three is', three, 'n', 'four is', four)
    
    --OUTPUT>
    one is 1 
    two is 2 
    three is 3 
    four is 4
    

    В этом случае Python позволяет использовать множественное присваивание совместно с функцией range():

    one, two, three, four = range(1,5)
    print(' one is',one,'n', 'two is', two, 'n', 'three is', three, 'n', 'four is', four)

    Предположим, у нас есть два списка: первый — с именами друзей, а второй — это города, где они живут. Нужно объединить элементы списков в словарь вида «имя: город».

    Это можно сделать с помощью цикла for:

    friends = ["Катя", "Лена", "Даша", "Костя", "Дима"]
    cities = ["Москва", "Пенза", "Екатеринбург", "Минск"]
    friends_cities = {}
    for i in range(min(len(friends), len(cities))):
       friends_cities[friends[i]] = cities[i]
    print(friends_cities)
    
    --OUTPUT>
    {'Катя': 'Москва', 'Лена': 'Пенза', 'Даша': 'Екатеринбург', 'Костя': 'Минск'}
    

    Однако в Python встроена функция zip, которая делает то же самое — короче и проще.

    Её аргументами могут быть списки, кортежи, множества и словари. Функция zip возвращает итератор, объединяющий элементы из объектов-источников.

    Например, передадим в zip аргументами строку, список и множество:

    arg1 = 'абвгдеж'
    arg2 = ['1','2','3','4','5']
    arg3 = {'!','@','#','$','%','^'}
    
    zip_obj = zip(arg1, arg2, arg3)
    print(zip_obj)
    
    for i in zip_obj:
       print(i)
    
    --OUTPUT>
    <zip object at 0x000001D228F06BC0>
    ('а', '1', '!')
    ('б', '2', '@')
    ('в', '3', '#')
    ('г', '4', '$')
    ('д', '5', '%')
    

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

    Теперь создадим словарь «имя: город» с использованием zip. Код будет выглядеть так:

    friends = ["Катя", "Лена", "Даша", "Костя", "Дима"]
    cities = ["Москва", "Пенза", "Екатеринбург", "Минск"]
    friends_cities = dict(zip(friends, cities))
    print(friends_cities)
    
    --OUTPUT>
    {'Катя': 'Москва', 'Лена': 'Пенза', 'Даша': 'Екатеринбург', 'Костя': 'Минск'}
    

    Функция zip работает до тех пор, пока не закончатся элементы в самом коротком из итерируемых объектов-аргументов.

    Если нужно ориентироваться на самый длинный список, то используют функцию zip_longest из модуля itertools:

    from itertools import zip_longest
    
    friends = ["Катя", "Лена", "Даша", "Костя", "Дима"]
    cities = ["Москва", "Пенза", "Екатеринбург", "Минск"]
    friends_cities = dict(zip_longest(friends, cities))
    print(friends_cities)
    
    --OUTPUT>
    {'Катя': 'Москва', 'Лена': 'Пенза', 'Даша': 'Екатеринбург', 'Костя': 'Минск', 'Дима': None}
    

    В среде разработки приложений PyCharm есть инструменты, которые помогают проводить рефакторинг. Они доступны через пункт Refactor главного меню. Научимся улучшать код с их помощью.

    Открываем IDE и устанавливаем параметры рефакторинга в настройках редактора (File | Settings | Editor | Code Editing) в разделе Refactorings.

    Если мы выберем режим In modal dialogs (во всплывающих окнах), то при использовании инструментов Extract/Introduce редактирование имён параметров, констант, полей и переменных будет происходить в открывающихся модальных окнах:

    Если же мы предпочтём режим In the editor (в редакторе), то имена параметров, констант, полей и переменных будем редактировать прямо в редакторе:

    Для примера установим In modal dialogs.

    Теперь создадим в окне редактора новый проект (File | New Project) с именем refactorProject. Добавим в него новый файл (File | New | Python File), а назовём его, скажем, refactor.py.

    Разберём извлечение метода в PyCharm на одном из наших примеров:

    while True :
     a1 = int(input( "Введите цену товара: "))
     if a1 < 0 :
       print ("Значение не должно быть отрицательным!")
     else :
       break
    
    while True :
     a2 = int(input("Введите количество товара: "))
     if a2 < 0 :
       print ("Значение не должно быть отрицательным!")
     else :
       break
    
    a3 = a1 * a2
    print("Стоимость товара: ", a3)

    Копируем этот код в окно редактора:

    Выделим первый цикл while и используем инструмент Refactor | Extract/Introduce | Method из главного или контекстного меню (горячие клавиши Ctrl + Alt + M).

    В нужное поле открывшегося окна вводим название функции — input_value ():

    Чтобы добавить параметр функции, выделим подсказку «Введите стоимость товара: » и выберем в главном/контекстном меню инструмент Refactor | Introduce Parameter (Ctrl + Alt + P):

    В появившемся модальном окне введём название параметра — prompt (в переводе с английского — «подсказка»):

    У нас получилось:

    def input_value(prompt):
      while True:
         a1 = int(input(prompt))
         if a1 < 0 :
             print ("Значение не должно быть отрицательным!")
         else :
             return a1

    Заменим название переменной a1 на value с помощью инструмента рефакторинга «Переименование». Выделим a1 и выберем Refactor | Rename (Shift + F6):

    Дадим новым переменным осмысленные имена: price, quantity, cost.

    Теперь заменим дубли в нашем коде на вызовы функции с соответствующими значениями параметров. Исправленный код будет выглядеть так:

    def input_value(prompt):
      while True:
         value = int( input( prompt ) )
         if value < 0 :
             print ("Значение не должно быть отрицательным!")
         else :
             return value
    
    price = input_value("Введите цену товара: ")
    quantity = input_value("Введите количество товара: ")
    cost = price * quantity
    print("Стоимость товара: ", cost)

    Как мы помним, переменной cost присваивается результат простого выражения (price * quantity) и больше с ней ничего не делается.

    Поэтому нам можно от неё избавиться — заменить обращения к этой переменной выражением price * quantity. Сделаем это с помощью инструментов рефакторинга.

    Выделим переменную cost и выберем в меню Refactor инструмент Inline («Встраивание») или вызовем его горячими клавишами Ctrl + Alt + N.

    PyCharm определит число вхождений и попросит подтвердить действие:

    Нажимаем OK. Программа убирает выражение, в котором создаётся переменная cost, и везде подставляет вместо неё price * quantity:

    def input_value(prompt):
      while True:
         value = int( input( prompt ) )
         if value < 0 :
             print ("Значение не должно быть отрицательным!")
         else :
             return value
    
    price = input_value ("Введите цену товара: ")
    quantity = input_value ("Введите количество товара: ")
    print ("Стоимость товара: ", price * quantity)

    Чем объёмнее код, тем выгоднее применять инструменты рефакторинга. С ними уборка в коде ускоряется и ошибки сводятся к минимуму.

    Мы рассмотрели лишь несколько приёмов рефакторинга — в Python их намного больше. Будучи быстрыми и несложными, вместе они здорово повышают качество проекта. Главное — проводить рефакторинг регулярно и не забывать затем тестировать приложение.

    Учись бесплатно:
    вебинары по программированию, маркетингу и дизайну.

    Участвовать

    Школа дронов для всех
    Учим программировать беспилотники и управлять ими.

    Узнать больше

    Понравилась статья? Поделить с друзьями:
  • Unturned как изменить вид
  • Untrusted system file c windows system32 opengl32 dll как исправить
  • Untrusted system file c windows system32 normaliz dll как исправить
  • Untrusted system file c program files rockstar games social club libcef dll ошибка
  • Untracked files prevent checkout как исправить