импортиране на модул: NameError: името не е дефинирано

Как да дефинирам функцията в програмата за импортиране, така че да е видима вътре в imported? Опитах това

importer.py is

def build():
    print "building"

build()

import imported

При което imported.py е просто

build()

И все пак това се проваля

building
Traceback (most recent call last):
  File "C:\Users\valentin\Desktop\projects\maxim\miniGP\b01\evaluator\importer.py", line 6, in <module>
    import imported
  File "C:\Users\valentin\Desktop\projects\maxim\miniGP\b01\evaluator\imported.py", line 1, in <module>
    build()
NameError: name 'build' is not defined

Актуализация След като получих отговор да направя цикличното импортиране, така че импортирането и импортирането да зависят едно от друго, смятам, че трябва да поясня, че това не винаги е добре. Целта ми е да уточня някаква обща стратегия в импортирания модул. Той ще използва някои дефинирани от потребителя функции, напр. build. Потребителят дефинира необходимата функция(и) и извиква стратегията. Въпросът е, че споделената стратегия не трябва да зависи от определени потребителски дефиниции. Вярвам, че вместо import, имам нужда от нещо като evaluate(imported.py), което според мен е основна функция във всеки скриптов език, включително Python. irc://freenode/python настоява да използвам import, но не разбирам как.


person Val    schedule 31.10.2013    source източник
comment
Част от нашето объркване е, защото точно това прави import, като страничен ефект от импортирането на самия модул. (Така че, ако foo.py съдържа bar = 1 + 1 и вие import foo, тогава имате достъп до foo.bar == 2, защото foo.py е оценено!)   -  person Izkata    schedule 04.11.2013
comment
Не разбирам за какво объркване говориш.   -  person Val    schedule 04.11.2013


Отговори (3)


importer.py

def build():
   print("building")

build() #this extra call will print "building" once more.

imported.py

from importer import build
build()

Имайте предвид, че importer.py и imported.py трябва да са в една и съща директория. Надявам се това да реши проблема ви

person SujitS    schedule 31.10.2013
comment
Няма ли да създаде учебна препратка? Колко пъти се изпълнява print(building)? - person Val; 31.10.2013
comment
толкова, колкото извиквате функцията build(). За моя случай ще се отпечата само веднъж. - person SujitS; 31.10.2013
comment
Всъщност го извиквам два пъти и всъщност се изпълнява 3 пъти. Чудя се защо не милион: вие извиквате importer.py, който отпечатва и импортира imported.py, който импортира importer.py, който отпечатва(изгражда) и импортира impoted, който импортира importer, който отпечатва(изгражда) и импортира внос, който... - person Val; 31.10.2013
comment
Опитахте ли го вече! използването на импортиране означава да направите препратка към вашия модул, а не да го изпълните. И извикване на функция build() вътре в imported всъщност ще извика функцията от importer.py, която след това се изпълнява не повече от веднъж. Така че опитайте, преди да го попитате - person SujitS; 31.10.2013
comment
Опитах го и в моя лаптоп е само веднъж, а с функцията 2 build() два пъти.. Проверете отново проблема си, сигурен съм, че не е начинът на python - person SujitS; 31.10.2013
comment
Всичко, което направих, е префиксът imported.py с from importer import build реда, който сте препоръчали - person Val; 31.10.2013
comment
След това трябва да работи, проверете вашия importer.py, може да имате две функции build(); един за дефиниция и друг е извикване на функция. Това вече не е проблем с вноса. - person SujitS; 31.10.2013
comment
Добре, не съм забелязал, че ме помолихте да пренапиша и importer.py. Проблемът липсваше from importer import build в imported.py. Вашият отговор обаче не го разрешава. Не мога да импортирам импортера, защото imported е обичайна част, която трябва да работи във всеки контекст (произволен импортер, независимо от това коя build функция е дефинирал). Внесените не трябва да бъдат обвързани с конкретен вносител. - person Val; 31.10.2013
comment
Открих, че имам нужда от execfile. За съжаление врагът не ми позволява да направя това като отговор. Но нека запазим правилния отговор тук. - person Val; 31.10.2013
comment
@Val Ако имате множество реализации на код, дефиниращ build, и само една трябва да бъде извикана в зависимост от определен контекст, вие дори не задавате правилния въпрос. Слязохте в заешка дупка в грешната посока. Моля, в бъдеще питайте действително за проблема, пред който сте изправени, а не за това, което предполагате, че ще бъде отговорът. - person Izkata; 04.11.2013
comment
@Izkata Питах това в irc://freenode/#python и ми казаха, че трябва да отделя обща част в друг файл и да използвам imports. Отказаха да обяснят как всъщност трябва да внасям. Затова трябваше да прибягна тук. Какво сбърках? - person Val; 04.11.2013
comment
@Val Все още не знаем какво се опитвате да направите, така че този отговор наистина беше най-доброто, което можем да направим, и не е това, което искате. Моля, прочетете това и задайте въпрос какво всъщност се опитвате да направите, ако все още имате нужда от помощ. - person Izkata; 04.11.2013
comment
@Izkata, актуализирах въпроса, обяснявайки ограничението на най-доброто, което можете да направите, и защо execfile е по-подходящ за моята задача. Чудя се защо експертите по Python са толкова слепи, за да забележат това и изискват повече подробности, без да обясняват какво не е ясно в предоставеното. Изморих се да обяснявам защо имам нужда от това. Няма да правя повече. Слушайте Фейнман как обяснява, че има крайната причина да имате нужда от нещо youtube.com/watch?v=36GT2zI8lVA Смятам, че това е достатъчно, за да кажа, че ледът е хлъзгав. Питаш why без дори да изясниш какво имаш предвид. - person Val; 04.11.2013

Импортирането не се включва: те са идемпотентни и винаги трябва да са в горната част на модул.

Няма кръговрат; след като import foo се види, следващите екземпляри на import foo няма да заредят модула отново.

Получавате NameError, защото в контекста на imported.py няма име build, то е известно като importer.build().

Нямам представа какво се опитвате да направите с толкова странно структуриран код.

person msw    schedule 31.10.2013
comment
Импортерът дефинира някои функции и извиква общ код. По този начин вие параметризирате вашия общ код. Няма нищо странно в тази нормалност. - person Val; 31.10.2013

Знам, че това е богохулство, но нещото, което позволява импортирането на модул без обвързване на импортирания с импортера, е лесно достъпно в Python като скриптов език. Винаги можете да оцените файл с execfile

person Val    schedule 31.10.2013
comment
execfile() не е богохулство, това е просто лоша идея. Освен това е доста различно от импортирането. От въпроса ви става ясно, че това е, което искате, но не е ясно защо искате това. Това не е нормално нещо в Python, по никакъв начин. Вместо това структурирайте проекта си така, че да отговаря на Python. - person Thomas Wouters; 31.10.2013