2013-09-24 4 views
1

Я думаю, что есть способ распаковать атрибуты объекта. Обычно делают это включает в себя серию:Распаковка переменных объекта в python

self.x = x 
self.y = y 
... #etc. 

Однако это должно быть возможно сделать это лучше.

Я думаю о чем-то вроде:

def __init__(self,x,y,z): 
    self.(x,y,z) = x,y,z 

или, может быть:

с х, у, г распаковки (само)

или даже функции, как:

def __init__(self,x,y,z): 
    unpack(self,x,y,z) 

Любые идеи? Или есть еще какой-нибудь питонический способ сделать это?

+4

'для имени в ('x', 'y', 'z'): setattr (self, name, locals() [name]) ' – falsetru

+0

В чем проблема с выполнением это нормальный путь? –

+0

, если у вас есть предсказуемый шаблон в ваших атрибутах объекта, это означает, что вы должны были создать dict, чтобы собрать эти значения, и метод getter для доступа к ним. Написание непредсказуемого атрибута - это то, что человек должен делать. – Mai

ответ

3

Вы можете использовать namedtuple, который делает то, что вы хотите:

Пример кода из официальной Python документации:

Point = namedtuple('Point', ['x', 'y'], verbose=True) 

Приведенный выше код эквивалентен:

class Point(tuple): 
    'Point(x, y)' 

    __slots__ =() 

    _fields = ('x', 'y') 

    def __new__(_cls, x, y): 
     'Create a new instance of Point(x, y)' 
     return _tuple.__new__(_cls, (x, y)) 

    @classmethod 
    def _make(cls, iterable, new=tuple.__new__, len=len): 
     'Make a new Point object from a sequence or iterable' 
     result = new(cls, iterable) 
     if len(result) != 2: 
      raise TypeError('Expected 2 arguments, got %d' % len(result)) 
     return result 

    def __repr__(self): 
     'Return a nicely formatted representation string' 
     return 'Point(x=%r, y=%r)' % self 

    def _asdict(self): 
     'Return a new OrderedDict which maps field names to their values' 
     return OrderedDict(zip(self._fields, self)) 

    def _replace(_self, **kwds): 
     'Return a new Point object replacing specified fields with new values' 
     result = _self._make(map(kwds.pop, ('x', 'y'), _self)) 
     if kwds: 
      raise ValueError('Got unexpected field names: %r' % kwds.keys()) 
     return result 

    def __getnewargs__(self): 
     'Return self as a plain tuple. Used by copy and pickle.' 
     return tuple(self) 

    __dict__ = _property(_asdict) 

    def __getstate__(self): 
     'Exclude the OrderedDict from pickling' 
     pass 

    x = _property(_itemgetter(0), doc='Alias for field number 0') 

    y = _property(_itemgetter(1), doc='Alias for field number 1') 

Вот как это использовать:

>>> p = Point(11, y=22)  # instantiate with positional or keyword arguments 
>>> p[0] + p[1]    # indexable like the plain tuple (11, 22) 
33 
>>> x, y = p    # unpack like a regular tuple 
>>> x, y 
(11, 22) 
>>> p.x + p.y    # fields also accessible by name 
33 
>>> p      # readable __repr__ with a name=value style 
Point(x=11, y=22) 

Источник: http://docs.python.org/2/library/collections.html#namedtuple-factory-function-for-tuples-with-named-fields

Одна вещь стоит отметить, что namedtuple не что иное, как обычный класс, и вы могли бы создать класс, который наследует от него.

+0

Это скопировано и вставлено здесь: http://docs.python.org/2/library/collections.html#collections.namedtuple – Mai

+0

Благодарим вас за добавление источника назад :) – Mai

0

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

более общий рецепт для создания экземпляра переменные, основанные на именах атрибутов объясняется здесь http://code.activestate.com/recipes/286185-automatically-initializing-instance-variables-from/

0

Я уверен, что вы можете сделать это: self.x, self.y, self.z = х, у, г