Как изменить имя модуля Python?

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

Ответов (8)

Решение

Да, вам следует переименовать файл. Лучше всего было бы после того, как вы сделали это , чтобы удалить oldname.pyc и oldname.pyo скомпилированные файлы (если он присутствует) из системы, в противном случае модуль будет ввозом под старым названием тоже.

Где бы вы хотели разместить эту __module__ переменную, чтобы исходный сценарий знал, что импортировать? Модули распознаются по именам файлов и просматриваются по путям, указанным в sys.path переменной.

Итак, вам нужно переименовать файл, а затем удалить его oldname.pyc, чтобы убедиться, что все работает правильно.

Если вы действительно хотите импортировать файл oldname.py с помощью оператора import newname, есть трюк, который делает это возможным: импортируйте модуль куда-нибудь со старым именем, а затем вставьте его sys.modules с новым именем. Последующие операторы импорта также найдут его под новым именем. Пример кода:

# this is in file 'oldname.py'
...module code...

Использование:

# inject the 'oldname' module with a new name
import oldname
import sys
sys.modules['newname'] = oldname

Теперь вы можете использовать свой модуль везде, где есть import newname .

У меня была такая проблема с bsddb. Мне пришлось установить модуль bsddb3, но сотни скриптов импортировали bsddb. Вместо того, чтобы изменять импорт во всех из них, я извлек "яйцо" bsddb3 и создал мягкую ссылку в каталоге site-packages, так что "bsddb" и "bsddb3" были одним и тем же для python.

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

func.__module__ = module

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

def set_module(module):
    """Decorator for overriding __module__ on a function or class.
    Example usage::
        @set_module('numpy')
        def example():
            pass
        assert example.__module__ == 'numpy'
    """
    def decorator(func):
        if module is not None:
            func.__module__ = module
        return func
    return 

а затем используйте

@set_module('my_module')
def some_func(...):

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

Этот пример взят из исходного кода numpy: https://github.com/numpy/numpy/blob/0721406ede8b983b8689d8b70556499fc2aea28a/numpy/core/numeric.py#L289

У каждого класса есть __module__ свойство, хотя я считаю, что его изменение не изменит пространство имен класса.

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

Лучше всего переименовать файл.

Вы можете изменить имя, используемое для модуля при импорте, используя as:

import foo as bar
print bar.baz

Когда вы это делаете, import module_name интерпретатор Python ищет файл module_name .extensionв PYTHONPATH. Так что изменить это имя без изменения имени файла невозможно. Но, конечно, вы можете:

import module_name as new_module_name

или даже

import module_name.submodule.subsubmodule as short_name

Полезно, например. для написания кода БД.

import sqlite3 as sql
sql.whatever..

А затем переключить, например. sqlite3 чтобы pysqlite вы просто изменить импортную линию