2012-02-24 3 views
1

Есть ли способ группировать имена вместе в python, повторно назначать им ru masse?Назначение последовательности более высокого порядка Python?

В то время как мы можем сделать:

a,b,c = (1,2,3) 

Я хотел бы быть в состоянии сделать что-то вроде:

names = a,b,c 

*names = (3,2,1) # this syntax doesn't work 

a,b,c == (3,2,1) #=> True 

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

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

a = 1 
b = 2 
c = 3 

sequence = (a,b,c) 
+5

Это, похоже, еще один пример смешивания данных с именами переменных. –

+3

См. Http://nedbatchelder.com/blog/201112/keep_data_out_of_your_variable_names.html – delnan

+0

@SvenMarnach, похоже, в наши дни очень много. –

ответ

1

Это?

>>> from collections import namedtuple 
>>> names = namedtuple('names', ['a','b','c']) 

>>> thing= names(3,2,1) 
>>> thing.a 
3 
>>> thing.b 
2 
>>> thing.c 
1 
+0

Да, может быть, на самом деле. – Marcin

1

Вы должны использовать dict:

>>> d = {"a": 1, "b": 2, "c": 3} 
>>> d.update({"a": 8}) 
>>> print(d) 
{"a": 8, "c": 3, "b": 2} 
+2

Я действительно не вижу, как это соответствует вопросу. – HexTree

+0

HexTree: первое предложение просто кричит словарь: «Есть ли способ группировать имена вместе в python, чтобы многократно назначать им en masse?». – orlp

+1

Проблема с этим ответом состоит в том, что вам все равно нужно повторять имена каждый раз, когда вы хотите переназначить, что именно то, чего избегал OP. –

2

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

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

names = "a b c".split() 
d = dict(zip(names, (1, 2, 3))) 
d.update(zip(names, (3, 2, 1))) 

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

class X(object): 
    def __init__(self, a, b, c): 
     self.update(a, b, c) 
    def update(self, a, b, c) 
     self.a, self.b, self.c = a, b, c 

x = X(1, 2, 3) 
x.update(3, 2, 1) 
print x.a, x.b. x.c 

Это отражает то, что вы хотите заблокировать a, b и c к некоторой общей структуре, но сохранить возможность доступа к ним по имени.

+0

Я не пытаюсь использовать имена в качестве данных; Я действительно хочу использовать их как отдельные переменные. – Marcin

+2

@Marcin: Но попытка помещать имена внутри метафайлов 'names' означает * обрабатывать их как данные. –

+0

Я не уверен, что это полезный способ определить «смешивание данных с именами переменных», если вы не выполняете операции над именами за пределами обычных операций чтения и настройки. – Marcin

-1

Не уверен, является ли то, что вы хотите ...

>>> a,b,c = (1,2,3) 
>>> names = (a,b,c) 
>>> names 
(1, 2, 3) 
>>> (a,b,c) == names 
True 
>>> (a,b,c) == (1,2,3) 
True 
+0

Следует избегать многократного ввода '(a, b, c)'. – Marcin

0

Ну, вы не должны делать это, так как это потенциально небезопасно, но вы можете use the exec statement

>>> names = "a, b, c" 
>>> tup = 1,2,3 
>>> exec names + "=" + repr(tup) 
>>> a, b, c 
(1, 2, 3) 
+0

Я не вижу, как это продвижение по простому назначению последовательности. – Marcin

+0

Это вовсе не аванс! Это ужасная идея. Но это позволяет вам сделать что-то ближе к тому, что казалось вам нужным .... –

1

Я понял, что «экзотический» синтаксис, вероятно, не нужен. Вместо того, чтобы следующие добивается того, чего я хотел: (1), чтобы избежать повторения имен и (2), чтобы захватить их в виде последовательности:

sequence = (a,b,c) = (1,2,3) 

Конечно, это не позволит:

*names = (3,2,1) # this syntax doesn't work 

a,b,c == (3,2,1) #=> True 

Таким образом, это не облегчит повторное присвоение одной и той же группе имен, не повторяя эти имена повторно (за исключением цикла).

0

Python имеет такую ​​элегантную систему пространств имен:

#!/usr/bin/env python 

class GenericContainer(object): 
    def __init__(self, *args, **kwargs): 
     self._names = [] 
     self._names.extend(args) 
     self.set(**kwargs) 
    def set(self, *args, **kwargs): 
     for i, value in enumerate(args): 
      self.__dict__[self._names[i]] = value 
     for name, value in kwargs.items(): 
      if name not in self._names: 
       self._names.append(name) 
      self.__dict__[name] = value 
    def zip(self, names, values): 
     self.set(**dict(zip(names, values))) 

def main(): 
    x = GenericContainer('a', 'b', 'c') 
    x.set(1, 2, 3, d=4) 
    x.a = 10 
    print (x.a, x.b, x.c, x.d,) 
    y = GenericContainer(a=1, b=2, c=3) 
    y.set(3, 2, 1) 
    print (y.a, y.b, y.c,) 
    y.set(**dict(zip(('a', 'b', 'c'), (1, 2, 3)))) 
    print (y.a, y.b, y.c,) 
    names = 'x', 'y', 'z' 
    y.zip(names, (4, 5, 6)) 
    print (y.x, y.y, y.z,) 

if __name__ == '__main__': 
    main() 

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

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