Как вызвать функцию Python, как в Javascript - PullRequest
2 голосов
/ 07 мая 2011

если я сделаю это, все будет в порядке:

def a():
    b = [1,2,3]
    def d():
        print b
    d()

a()

, но у меня есть много методов, нуждающихся в функции d , поэтому я должен определить ее вне функции a , но он показывает ошибку:

def d():
    print b
def a():
    b = [1,2,3]
    d()

a()

error:

  File "c.py", line 21, in <module>
    a()
  File "c.py", line 19, in a
    d()
  File "c.py", line 16, in d
    print b
NameError: global name 'b' is not defined

, поэтому у меня много разных переменных, например b в разных функциях, поэтому я не хочуОтправьте переменную следующим образом:

def d(b1,b2,b3,b4,b5):
    print b1,b2,b3,b4,b5

, что не очень просто, поэтому я делаю это так:

d = \
'''
def d():\n
    print b
'''
def a():
    b = [1,2,3]
    c = eval(d)
    c()

a() 

, но также выдает ошибку:

  File "c.py", line 16, in <module>
    a()
  File "c.py", line 13, in a
    c = eval(d)
  File "<string>", line 2
    def d():
      ^

так что я могу сделать,

спасибо

Ответы [ 5 ]

4 голосов
/ 07 мая 2011

Вероятно, вас смущает область видимости javascript, которая противоположна областям действия Python. Прочтите официальное руководство по Python о областях и пространствах имен , прежде чем идти дальше! Вам также может пригодиться этот доклад Иана Бикинга: Javascript для людей, которые знают Python . Он прекрасно справляется с различиями между двумя языками.

В этом случае вы пытаетесь получить доступ к объекту с именем, которое определено в пространстве имен другой функции, что означает, что он не может узнать об этом. В идеале нужно переписать d (), чтобы он принял аргумент и передал его b. Вы также можете объявить b как глобальное, используя global, но вам следует избегать этого.

def d():
    print b # b is defined in a so it's only available in a's local namespace
def a():
    b = [1,2,3] 
    d() # if you rewrite d to accept an argument, you can pass it b and this will work

Сделайте это:

def d(b): # accepts an argument now
    print b

def a():
    b = [1,2,3]
    d(b) # calls d with an argument of b

Если вам интересно, какие имена находятся в различных областях, вы можете сделать это:

import __builtin__
def d():
    print dir(__builtin__) # built-in names
    print dir(globals()) # global names
    print dir(locals()) # local names, defined in d 

Я думаю, вы найдете пространство имен / область видимости Python довольно интуитивно понятным.

3 голосов
/ 07 мая 2011

Похоже, вы хотите превратить a в класс:

class A(object):
    b = [1,2,3]
    def d():
        print b

A.d()
A.b = [4, 5, 6]
A.d()
1 голос
/ 07 мая 2011

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

0 голосов
/ 07 мая 2011

Просто чтобы исправить существующие хорошие ответы от Mikel и Zeekay, вот разница в JavaScript. То, что вы, вероятно, имели:

function d() {
  print(b);
}

function a() {
  b = [1,2,3];
  d();
}

Но то, что вы получаете в Python, эквивалентно этому:

function d() {
  print(b);
}

function a() {
  var b = [1,2,3];
  d();
}

(помните var b во второй версии). Если вы знаете JavaScript, вы получите разницу. Передача аргументов, как предполагается, предпочтительнее. Использование ключевого слова global было бы другим (менее предпочтительным) способом.

0 голосов
/ 07 мая 2011

Не видя JavaScript, который вы пытаетесь эмулировать, я могу только догадываться.

Но почему бы вам просто не передать b на d:

def d(b):
    print b
def a():
    b = [1,2,3]
    d(b)

a()

Или, если это не вариант, возможно, вы могли бы объявить b глобальным:

b = []
def d():
    print b
def a():
    global b
    b = [1,2,3]
    d()

a()

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

def test(b):
    def t(f):
        def d():
            print b
            return f(b)
        return d
    return t

@test([1,2,3])
def a(b):
    pass

a()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...