определяющая переменная из строки - PullRequest
4 голосов
/ 15 июля 2010

Я пытаюсь определить переменную внутри функции. vars () показывает, что переменная создана, но выдает мне NameError: исключение. Что я делаю не так?

def a(str1):
    vars() [str1] =  1
    print vars()
    print b


a('b')

выход:

{'str1': 'b', 'b': 1}

исключение:

NameError: global name 'b' is not defined

Ответы [ 3 ]

4 голосов
/ 15 июля 2010

Вы вызываете неопределенное поведение.Из документации vars():

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

Другие ответы дают возможные решения.

2 голосов
/ 15 июля 2010

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

exec(str1 + '=1')

Это выполнит b=1

1 голос
/ 15 июля 2010

Если вы не понимаете, почему конструкция не работает, то и следующий человек, который должен прочитать ваш код, тоже не будет.Если вы имеете в виду

b = 1   

, вы должны это сказать.В этом случае vars() предоставляет вам доступ к локальному словарю функции, поэтому ваш код эквивалентен

def a():
   b = 1

, где b локально по отношению к a и испаряется, когда выходит из области действия при выходе изa.

преждевременная оптимизация - корень попытки многих людей переосмыслить Python

from itertools import izip
import timeit

import msw.wordlist

def zip_list(p):
    """construct a dictionary of length 100 from a list of strings"""
    return dict(zip(p[:100], p[100:]))

def izip_list(p):
    """as zip_list but avoids creating a new list to feed to dict()"""
    return dict(izip(p[:100], p[100:]))

def pass_list(p):
    """take 100 elements of a list and do nothing"""
    for i in p[:100]:
        pass

def exec_pass_list(p):
    """exec() a no-op 100 times"""
    for i in xrange(100):
        exec('pass')


# returns a list of 64'000 unique lowercase dictionary words for tests
words = msw.wordlist.Wordlist()
words.shuffle()
words = words[:200]
print 'words', words[:5], '...'

for func in ['zip_list', 'izip_list', 'pass_list', 'exec_pass_list']:
    t = timeit.Timer('%s(words)' % func,
            'from __main__ import words, %s' % func)
    print func, t.repeat(number=10**5)

, что приводит к:

words ['concatenated', 'predicament', 'shtick', 'imagine', 'stationing'] ...
zip_list [1.8603439331054688, 1.8597819805145264, 1.8571949005126953]
izip_list [1.5500969886779785, 1.5501470565795898, 1.5536530017852783]
pass_list [0.26778006553649902, 0.26837801933288574, 0.26767921447753906]
exec_pass_list [74.459679126739502, 75.221366882324219, 77.538936853408813]

Я не удосужился попытаться реализовать то, что пытался сделать OP, потому что отсутствие в 50 раз медленнее, чтобы не создавать сортировку по словарю, делает дальнейшее тестирование довольно глупым.

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