Как я могу препятствовать тому, чтобы модуль Python импортировал себя?

Причиной это твердо, является безопасность. Classloaders предназначены, чтобы быть неизменными; Вы не должны быть в состоянии волей-неволей добавить классы к нему во времени выполнения. Я на самом деле очень удивлен что работы с системой classloader. Вот то, как Вы делаете это делающий Ваш собственный дочерний classloader:

URLClassLoader child = new URLClassLoader(
        new URL[] {myJar.toURI().toURL()},
        this.getClass().getClassLoader()
);
Class classToLoad = Class.forName("com.MyClass", true, child);
Method method = classToLoad.getDeclaredMethod("myMethod");
Object instance = classToLoad.newInstance();
Object result = method.invoke(instance);

Болезненный, но там это.

13
задан Jason Baker 4 December 2009 в 16:54
поделиться

3 ответа

Редактировать : поскольку OP уже упомянул, что проблема заключается в том, что относительный импорт предпочтительнее абсолютного, самым простым решением конкретной проблемы OP является добавление в начале модуль из __future__ import absolute_import , который изменяет это «предпочтение» /ordering.

Следующее по-прежнему относится к щекотливой проблеме двух конфликтующих абсолютных импортов (что не похоже на то, с чем сейчас сталкивается OP ...):

После того, как вы импортировали модуль с именем x , этот модуль записан в sys.modules ['x'] - изменение sys.path по мере необходимости не изменяет sys.modules. Вам также нужно будет напрямую изменить sys.modules.

Например, рассмотрите:

$ cat a/foo.py
print __file__; import sys; sys.path.insert(0, "b"); del sys.modules["foo"]; import foo
$ cat b/foo.py
print __file__
$ python2.5 -c'import sys; sys.path.insert(0, "a"); import foo'
a/foo.py
b/foo.py

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

Не самый чистый подход, и, конечно, таким образом исходный модуль foo неизбежно больше не доступен извне (поскольку его запись sys.modules была перемещена), но вы можете играть дальнейшие хрупкие уловки по мере необходимости (спрятать sys.modules ["foo"] где-нибудь перед его удалением, после того как вы импортируете другой foo, поместите этот модуль в другое место и восстановите исходный sys.modules ["foo "] и т. Д. И т. Д.), В зависимости от ваших конкретных потребностей. (Конечно, избежать конфликта имен в первую очередь будет проще, чем вальсировать вокруг них таким образом; -)

. модули были перемещены), но вы можете использовать другие хрупкие уловки по мере необходимости (спрятать sys.modules ["foo"] где-нибудь перед его удалением, после того, как вы импортируете другой foo, поместите этот модуль в другое место и восстановите исходный sys.modules ["foo"] - и т. д. и т. д.), в зависимости от ваших конкретных потребностей. (Конечно, в первую очередь избежать конфликта имен почти всегда будет проще, чем вальсировать вокруг них таким образом; -).

модули были перемещены), но вы можете использовать другие хрупкие уловки по мере необходимости (спрятать sys.modules ["foo"] где-нибудь перед его удалением, после импорта другого foo поместите этот модуль в другое место и восстановите исходный sys.modules ["foo"] - и т. д. и т. д.), в зависимости от ваших конкретных потребностей. (Конечно, избежать конфликта имен в первую очередь будет проще, чем вальсировать вокруг них таким образом; -)

.
12
ответ дан 2 December 2019 в 00:03
поделиться

Не называйте это sqlalchemy.py?

Серьезно. Я думаю, что это проблема, которую должен решить абсолютный импорт. В python 2.5 этого не должно происходить, но я могу ошибаться

2
ответ дан 2 December 2019 в 00:03
поделиться

Возможно, вы просто обожаетесь из-за различий между запуском кода в интерактивном интерпретаторе и из файла. Удалите тест на то, что sys.path [0] пуст (при запуске из файла это не так), и импорт теперь должен работать так, как вы хотите.

$ more sqlalchemy.py
import sys
print sys.path[0]
sys.path.pop(0)
import sqlalchemy
print sqlalchemy.__file__
$ python sqlalchemy.py 
/Users/nad
/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/sqlalchemy/__init__.pyc
$ python
Python 2.6.4 (r264:75706, Oct 28 2009, 20:34:51) 
[GCC 4.0.1 (Apple Inc. build 5493)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys; print repr(sys.path[0])
''

РЕДАКТИРОВАТЬ: вышеуказанное применимо, если ваш основной модуль - sqlalchemy.py . Если ваш модуль импортируется другим модулем, вам также придется изменить sys.modules , как объясняет Алекс.

2
ответ дан 2 December 2019 в 00:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: