Переименуйте именованный параметр в Python, чтобы избежать конфликтов имен с помощью оператора import - PullRequest
0 голосов
/ 18 декабря 2018

Скажем, у меня есть функция foo в большом проекте Python с именованным аргументом bar:

def foo(bar=42):
  do_something_with_bar(bar)

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

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

from package import bar

def foo(bar=42):
  # how can I use the package.bar function here?
  do_something_with_bar(bar)

Я мог бы использовать что-то вроде:

from package import bar as package_bar

Но этот файл также содержит много вызовов bar так что это не надо.

Единственный способ увидеть эту работу - переименовать метод bar в package:

from package import bar
package_bar = bar

def foo(bar=42):
  do_something_with_bar(package_bar(bar))

или импортировать его нескольковремена (не проверено):

from package import bar, bar as package_bar

def foo(bar=42):
  do_something_with_bar(package_bar(bar))

Есть ли какой-нибудь способ переименовать параметр bar в функции foo без всех вызовов функции foo, прерывающей всю кодовую базу?

Ответы [ 5 ]

0 голосов
/ 18 декабря 2018

Я не знаю, правильно ли я понимаю ваш вопрос, но если вы просто хотите избежать конфликта пространства имен в этой конкретной функции, почему бы не импортировать его внутри функции?

def foo(bar=42):
  from package import bar as package_bar
  do_something_with_bar(package_bar(bar))

И вы можете добавить одинкомментарий наверху, чтобы напомнить себе.

0 голосов
/ 18 декабря 2018

Вы можете использовать globals() для ссылки на глобальные переменные.

def foo(bar=42):
    package_bar = globals()['bar']
    do_something_with_bar(package_bar(bar))

Это ничего не должно нарушать в вашей базе кода.

0 голосов
/ 18 декабря 2018

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

import package
from package import bar

def foo(bar=42):
    do_something_with_bar(package.bar(bar))

Вы по-прежнему импортируете модуль один раз, но теперь у вас есть два способа обращения к bar.

0 голосов
/ 18 декабря 2018

Если вам повезет, функция foo вызывается только с помощью "foo ()" или "foo (24)" и нигде с помощью "foo (bar = 42)", а затем вы можете поставить любое новое имя вместо barне ломая ничего.
В противном случае вам нужно выполнить поиск / поиск всех вызовов «foo (bar =») и заменить их, следя за возможными дополнительными пробелами, как в «foo (bar =».

0 голосов
/ 18 декабря 2018

Замените тело функции вызовом другой функции с аргументами с другими именами:

from package import bar

def foo(bar=42):
    return _foo(baz=bar)

def _foo(baz):
    do_something_with_bar(bar(baz))

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

...