2015-06-03 2 views
1

Я модифицирование простой рекурсивной функции, чтобы нарисовать кривую дракона с помощью черепахи:Python: есть ли способ использовать «неимпортированные» объекты в определениях функций?

def draw_dragon(t, order, size, L=turtle.left, R=turtle.right): 
    """ Draw a dragon curve """ 
    if not order: 
     t.forward(size) 
     return 

    size /= 1.41421 
    t.R(45) 
    draw_dragon(t, order-1, size, L, R) 
    t.L(90) 
    draw_dragon(t, order-1, size, R, L) 
    t.R(45) 

if __name__=="__main__": 
    import turtle 
    wn = turtle.Screen() 
    fred=turtle.Turtle() 
    draw_dragon(fred,6,200) 
    wn.exitonclick() 

Поскольку я еще не импортированы черепах в момент определения функции, интерпретатор дает мне "NameError: name 'turtle' is not defined".

Есть ли способ по-прежнему использовать функции модуля черепахи в моей функции draw_dragon без первоначального импорта их вне функции?

+2

В чем причина этого? Когда вы определяете 'draw_dragon', вы назначаете' turtle.left' 'L' kwarg; как мог интерпретатор узнать, что вы пытаетесь присвоить 'L', если вы этого не скажете (посредством оператора' import' или _definition_). Интерпретатор разбирает 'turtle.arg' (и он достаточно умен, чтобы разделить значение оскорбления на' .' и тем самым сообщить вам, что такое первый _submodule_, который не был найден) – CristiFati

+1

«Так как я еще не импортировал черепаху в то время определения функции "- ну почему бы и нет? – user2357112

+0

«Есть ли способ»? Возможно, с некоторым ужасным хакером. Есть ли способ _good_, соответствующий передовым методам, который также не нарушит анализ кода редакторов? Нет. (И зачем вам это нужно, а не просто перемещать «import» в верхнюю часть файла?) –

ответ

2

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

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

if __name__=="__main__": 
    import turtle 
    wn = turtle.Screen() 
    fred=turtle.Turtle() 
    draw_dragon(fred,6,200,turtle.left, turtle.right) 
    wn.exitonclick()   ^^^   ^^^ 

Затем измените L и R не имеют аргументов по умолчанию (они будут назначены функции через первоначального вызова), так что вы не получите NameErrors.

Теперь ваша функция должна знать, что такое методы, поскольку вы передали их функции через главный.

Возможно, вам стоит просто переместить вызов импорта в начало скрипта!

EDIT:

Ваш код все еще имеет некоторые странные идеосинкразий. Вместо того, чтобы пытаться передать методы из импортированных модулей в ваши функции, просто используйте функции, которые являются частью созданного вами объекта черепахи! Этот код должен работать, но это ТОЧНО не обычная практика вы хотите использовать ...

def draw_dragon(t, order, size, right, left, forward): 
    """ Draw a dragon curve """ 
    if order <= 0: 
     forward(size) 
     return 

    size /= 1.41421 
    right(45) 
    draw_dragon(t, order-1, size, right, left, forward) 
    left(90) 
    draw_dragon(t, order-1, size, left, right, forward) 
    right(45) 

if __name__=="__main__": 
    import turtle 
    wn = turtle.Screen() 
    fred=turtle.Turtle() 
    draw_dragon(fred, 6,200, turtle.left, turtle.right, turtle.forward) 
    wn.exitonclick() 

Лучше код будет таким:

from turtle import Screen, left, right, forward, speed, hideturtle 

def draw_dragon(order, size, left, right): 
    """ Draw a dragon curve """ 
    if order <= 0: 
     forward(size) 
     return 
    size /= 1.41421 
    right(45) 
    draw_dragon(order-1, size, right, left) 
    left(90) 
    draw_dragon(order-1, size, left, right) 
    right(45) 

if __name__=="__main__": 
    speed(0) 
    hideturtle() 
    wn = Screen() 
    draw_dragon(8,200, left, right) 
    wn.exitonclick() 
+0

спасибо - я изменил L и R, чтобы не иметь аргументов по умолчанию и передал функции черепахи draw_dragon. На этот раз я больше не получаю NameError, но вместо этого я получаю объект AttributeError: «Turtle» не имеет атрибута «R'' ... Затем я полностью избавился от параметра t черепахи t и скрипт начал работать - -почему это? – ladiesman

+0

«t» относится к объекту черепахи. Если вы использовали один из моих старых изменений, R теперь «turtle.right» Когда вы вызываете t.R, вы говорите «turtle.turtle.right», что, конечно же, не является функцией! R уже «turtle.right», поэтому вы можете просто сделать R (угол). –

+0

Последний вопрос: почему вам больше не нужны экземпляры Screen, Turtle и других настроек для новой версии? (Я предполагаю, что это связано с 'from xmodule import yfunc'? Еще раз спасибо :) – ladiesman

-1

Я думаю, что проблема может быть вызвана, что ваш turtle.py не находится в каталоге в sys.path.

+0

Я думаю, вы ошибаетесь;) Это приведет к 'ImportError', а не в' NameError'. Проблема заключается в том, что поскольку OP импортирует 'turtle' _after_ определение функции (которое ссылается на значения по умолчанию' turtle' fo аргумента), имя 'turtle' не существует, когда оператор' def' равен eval'd. –

+0

Я думал, что я импортировал черепаху, прежде чем функция eval'd ... так что во время оценки (не определяющей) функции, не должна ли черепаха уже быть видимой? – ladiesman

Смежные вопросы