Python __ импортирует __ беспорядок параметра

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

Файл test_1:

test_2 = __import__("test_2", {"testvar": 1})

Файл test_2:

print testvar

Это кажется, что должно работать и распечатать 1, но я получаю следующую ошибку, когда я выполняю test_1:

Traceback (most recent call last):
  File ".../test_1.py", line 1, in <module>
    print testvar
NameError: name 'testvar' is not defined

Что я делаю неправильно?

Править:

Как я прокомментировал позже, это - попытка заменить функции в графической библиотеке. Вот пример программы (который мой учитель записал), пользование, что библиотека:

from graphics import *
makeGraphicsWindow(800, 600)

############################################################
# this function is called once to initialize your new world

def startWorld(world):
    world.ballX = 50
    world.ballY = 300
    return world

############################################################
# this function is called every frame to update your world

def updateWorld(world):
     world.ballX = world.ballX + 3
     return world

############################################################
# this function is called every frame to draw your world

def drawWorld(world):
    fillCircle(world.ballX, world.ballY, 50, "red")

############################################################

runGraphics(startWorld, updateWorld, drawWorld)

Обратите внимание, что этот код разработан таким образом, что люди, которые никогда не имеют (или почти никогда) замеченный НИКАКОЙ код прежде (не только Python) смогли бы понять с небольшим усилием.

Пример для перезаписи функции:

Исходный код:

def drawPoint(x, y, color=GLI.foreground):
    GLI.screen.set_at((int(x),int(y)), lookupColor(color))

Введенный код:

# Where self is a window (class I created) instance.
def drawPoint(x, y, color = self.foreground):
  self.surface.set_at((int(x), int(y)), lookupColor(color))

Я предполагаю, что мой реальный вопрос: как я ввел бы глобальные функции/переменные в импортированный модуль перед выполнениями модуля...?

7
задан skeggse 31 May 2010 в 00:20
поделиться

4 ответа

Вы слишком стараетесь, вам нужен простой импорт. Определите переменную в одном модуле, скажем test1

testvar = 1

в test2 put

import test1
print test1.testvar
0
ответ дан 6 December 2019 в 21:10
поделиться

Как объясняется в документации, globals параметр к __import__ не вставляет дополнительные globals в импортируемый модуль, как вы, похоже, полагаете - действительно, то, что обычно передается туда, это globals() импортирующего модуля, так что такая инъекция была бы весьма проблематичной, если бы она произошла. Действительно, в документации __import__ конкретно сказано:

Стандартная реализация не использует свой аргумент locals вообще, и использует его глобальные значения только для определения контекст пакета при импорте утверждения.

Правка: если вам нужна инъекция, например, в пустой импортируемый модуль, как предложил ОП в комментарии, это легко, если вы согласны сделать это сразу после импорта:

themod = __import__(themodname)
themod.__dict__.update(thedict)

Тело импортируемого модуля не будет знать о еще не произошедших инъекциях, но это не имеет значения, если это тело все равно пусто;-). Сразу после импорта вы можете инжектировать до упора, и все последующие использования этого модуля будут видеть ваши инжекты, как если бы они были добросовестными связанными именами на уровне модуля (потому что они такие и есть;-).

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

import new, sys
themod = new.module(themodname)
sys.modules[themodname] = themod
themod.__dict__.update(thedict)

Edit: OP пытается прояснить ситуацию в редактировании вопроса...:

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

"Модуль запускается" не имеет особого смысла - модули загружаются (что выполняет их тело), только один раз (если повторно не загружаются явно позже)... они никогда не "запускаются" как таковые. Учитывая пустой модуль, вы сначала импортируете его (что ничего не выполняет, поскольку модуль пуст), а затем, если хотите, можете использовать смесь themodule.__dict__. update и присвоения атрибутов для заполнения модуля -- функции не автоматически вызываются при простом упоминании (как ОП выражает опасения, что они будут в комментарии), поэтому с ними можно обращаться так же, как с любой другой переменной в этом отношении (и в большинстве других, именно поэтому в Python говорят, что есть функции первого класса).

7
ответ дан 6 December 2019 в 21:10
поделиться

Похоже, вы хотите внедрить код в графическую библиотеку и запустить с его помощью примеры программ. Если это так, вы можете сделать это следующим образом:

import graphics
graphics.drawPoint = myDrawPoint

Вы также можете написать программу, которая принимает имя файла примера в качестве аргумента и выполняет это:

import sys
import graphics

def main():
    graphics.drawPoint = myDrawPoint
    execfile(sys.argv[1])
0
ответ дан 6 December 2019 в 21:10
поделиться

Как уже было сказано, функция __import__ не добавляет глобальные таблицы в новый модуль. Если вы хотите это сделать, я бы предложил добавить какую-нибудь функцию initialize(), которая присваивает значение заранее объявленной глобальной таблице, например, вот так:

gTable = {}
gInited = False

def initialize(table):
    if(not gInited):
        gTable = table
        gInited = True

def getGlobal(name):
    if(name in gTable):
        return gTable[name]
    else:
        throw NameError("name '"+name+"' is not defined")

def setGlobal(name, value):
    gTable[name] = value

def mod_main():
    print getGlobal("testvar")

и импортировать ее вот так:

import modGlobalsTest
modGlobalsTest.initialize({"testvar": 1})
modGlobalsTest.mod_main()

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

import foobar
def bar(x):
    return x+1
foobar.foo = bar

чтобы заменить foobar.foo на пользовательскую функцию bar.

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

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