2015-07-22 1 views
1

Я хотел бы создать временные переменные, видимые в ограниченном пространстве. Мне кажется, что вы можете сделать это с помощью инструкции «с», и я думаю, что есть конструкция, которая упрощает ее выполнение, но я не могу ее найти.Как создать переменные local с инструкцией?

Я хотел бы что-то вроде следующего (но он не работает так, конечно):

pronunciation = "E_0 g z @_1 m p l" 
# ... 
with pronunciation.split() as phonemes: 
    if len(phonemes) > 2 or phonemes[0].startswith('E'): 
     condition = 1 
    elif len(phonemes) < 3 and phonemes[-1] == '9r': 
     condition = 2 

Так есть простой способ, чтобы сделать эту работу, используя встроенные модули?

Спасибо!

+0

Со встроенным не работает таким образом. Почему вы не делаете phonemes = pronounciation.split(), а затем, если вам действительно нужно делать del фонем в конце? – muddyfish

ответ

2

Python создает локальные переменные с областью действия (как только имя используется, оно остается живым до конца функции).

Если вы действительно хотите ограничить область, то «del <var>», если вы хотите, чтобы он явно отбрасывался или создавал отдельную функцию, чтобы действовать как контейнер для более ограниченной области.

2

Вы можете создать метод

def process_pronunciation(pronunciation): 
    phonemes = pronunciation.split() 
    if len(phonemes) > 2 or phonemes[0].startswith('E'): 
     condition = 1 
    elif len(phonemes) < 3 and phonemes[-1] == '9r': 
     condition = 2 
    return condition 

При вызове метода, локальная переменная phonemes не будут доступны в глобальном пространстве имен.

pronunciation = "E_0 g z @_1 m p l" 
condition = process_phonemes(pronunciation) 
0

with заявление не имеет свою область применения, она использует окружающий объем (например, если с заявлением непосредственно в скрипте, а не в какой-либо функции, то она использует глобальное пространство имен, если используется with заявление внутри функции он использует пространство имен функции (область)).

Если вы хотите, чтобы операторы внутри блока с блоком выполнялись в своей локальной области, одним из возможных способов было бы перевести логику в функцию, таким образом логика будет работать в своей области (а не в окружении объем with

Пример -..

def function_for_with(f): 
    #Do something. 

with pronunciation.split() as phonemes: 
    function_for_with(phonemes) 

Пожалуйста, обратите внимание, что выше, не остановит phonemes от быть определен в окружающем объеме


Если вы тоже этого захотите (переместите phonemes в свою область), вы можете переместить полный оператор внутри функции. Пример -

def function_with(pronunciation): 
    with pronunciation.split() as phonemes: 
     #do stuff 

pronunciation = "E_0 g z @_1 m p l" 
function_with(pronunciation) 
1

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

class TempVar: 
    def __init__(self, loc, name, val): 
      self.loc = loc 
      self.name = name 
      self.val 

    def __enter__(self): 
      if self.name in self.loc: 
       self.old = self.loc[self.name] 
      self.loc[self.name] = self.val 

    def __exit__(self, *exc): 
      if hasattr(self, "old"): 
       self.loc[self.name] = self.old 
      else: 
       del self.loc[self.name] 

, то вы можете использовать его, чтобы получить временную переменную:

with TempVar(locals(), "tempVar", 42): 
    print(tempVar) 

Рабочим является то, что он изменяет dict, содержащие локальные переменные (которые поставляется конструктору через locals()) при входе и восстановлении его при выходе. Обратите внимание, что это зависит от того, что изменение результата, возвращаемого locals(), фактически изменяет локальное пространство имен - спецификация НЕ гарантирует это поведение.

Другая (и более безопасная) альтернатива, которая была указана, заключается в том, что вы можете определить отдельную функцию, которая будет иметь свой собственный охват. Помните, что законно устанавливать функции. Например:

def outer(): 
    def inner(tempVar): 
     # here tempVar is in scope 
     print(tempVar) 

    inner(tempVar = 42) 

    # here tempVar is out of scope 
0

расширяющейся на @ skyking отвечают, вот еще более волшебно реализация той же самой идеи, которая читает почти так же, как вы написали. Представляем: with var заявление!

class var: 
    def __init__(self, value): 
     import inspect 
     self.scope = inspect.currentframe().f_back.f_locals 
     self.old_vars = set(self.scope.keys()) 
     self.value = value 
    def __enter__(self): 
     return self.value 
    def __exit__(self, type, value, traceback): 
     for name in set(self.scope.keys()) - self.old_vars: 
      del self.scope[name] 

### Usage: 

line = 'a b c' 
with var (line.split()) as words: 
    # Prints "['a', 'b', 'c']" 
    print(words) 

# Causes a NameError 
print(words) 

Он делает все гадкое экстракцию локальных переменных и имен для вас! Как набухает. Если вы скроете это изворотливо, как я, и спрячьте определение в заявлении from boring_stuff import *, вы можете даже притворяться, что var - это ключевое слово для всех ваших смущенных коллег.

[1] Если вы действительно используете это, призрак мертвого попугая, вероятно, преследует вас навсегда. Другие ответы дают гораздо более разумные решения; это скорее шутка.