Конфликт имен модулей и объектов Python

Пожалуйста, обратите внимание на следующие выдержки из модулей Python:

foo.py:

class Foo:
  (...)

бар.py:

import foo

foo = foo.Foo()

Переменная foo, которая была объектом модуля, перезаписывается объектом Foo.

Я знаю, что могу использовать другие имена для объекта, например:

foobar = foo.Foo()

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

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

Это своего рода философский вопрос, но каков «правильный» способ справиться с этим потенциальным конфликтом имен объектов/модулей?


person João M. S. Silva    schedule 03.04.2013    source источник
comment
Я не думаю, что есть один правильный способ для всех модулей - это действительно зависит от имени модуля. Как указывает @F.J, вы можете импортировать его как что-то другое, но я бы скорее изменил имя своей переменной. Каковы имена модулей и классов в вашем конкретном случае?   -  person Ben Hoyt    schedule 04.04.2013
comment
Имена модулей/классов: камера, сеть, gpio, база данных и т. д.   -  person João M. S. Silva    schedule 04.04.2013
comment
Да, я вижу, как вы хотите назвать экземпляр camera.Camera() camera. Возможно, просто импортировать имена классов, а не целые модули, как в from camera import Camera? Затем вы можете безопасно использовать camera в качестве имени вашей переменной.   -  person Ben Hoyt    schedule 04.04.2013
comment
Спасибо, интересный вариант. Я не рассматривал это раньше, так как всегда импортирую полные модули. Я склонен считать частичный импорт опасным или менее надежным. Но в данном конкретном случае это может быть элегантным решением.   -  person João M. S. Silva    schedule 05.04.2013


Ответы (3)


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

import foo as foo_mod

foo = foo_mod.Foo()

Или альтернативно:

from foo import Foo

foo = Foo()

Это предотвращает конфликт имен, поэтому будет более очевидно, что переменная foo в вашем модуле не будет ссылаться на модуль с таким же именем.

person Andrew Clark    schedule 03.04.2013
comment
Спасибо, я не знал об этой альтернативе переименованию модуля. - person João M. S. Silva; 04.04.2013

В настоящее время я также отдаю предпочтение следующему стилю:

import foo

my_foo = foo.Foo()

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

person Ciro Santilli 新疆再教育营六四事件ۍ    schedule 12.05.2019

Этот шаблон, кажется, не беспокоит тех, кто использует Flask + Celery,

from celery import Celery

def make_celery(app):
    celery = Celery(
        app.import_name,
        backend=app.config['CELERY_RESULT_BACKEND'],
        broker=app.config['CELERY_BROKER_URL']
    )
    ...

Очевидно, правильный способ создания экземпляра этого класса — stalk = Celery() (хе-хе)

person xtian    schedule 01.05.2020