На основе sweeneyrod Ответ, я написал способ иметь несколько схожий синтаксис, используя строку с разделителями-запятыми и квадратные скобки.Использование:
thing = myclass()
thing['x,y'] = 3,6
x,y = thing['x,y']
thing['x,y,z'] = 1,2,3
Это дает
>>> x
3
>>> y
6
>>> thing.x
1
>>> thing.z
3
определение класса:
#user class
class myclass:
def __getitem__(self,keys):
keys = keys.split(',')
return tuple(getattr(self, attr) for attr in keys)
def __setitem__(self,keys,values):
keys = keys.split(',')
if len(keys) != len(values):
raise ValueError('too many values to unpack (expected %d)'%len(keys))
for attr,val in zip(keys, values):
setattr(self, attr, val)
def __delitem__(self,keys):
keys = keys.split(',')
for attr in keys:
delattr(self, attr)
вопросы:
- перекрывается с
__getitem__
, если вам это нужно.
- Не исключение безопасного (может
__setattr__
бросить исключение?)
Первоначально я думал использовать thing.grouping('x,y')=3,6
, но я забыл, что я не могу назначить вызов функции.
декоратор версия:
try:
from itertools import izip as zip #python 2
except:
pass #python 3 already has zip
#decorator
def attribute_tuple(cls):
if not hasattr(attribute_tuple,'initialized'):
attribute_tuple.initialized=True
def get(self,keys):
keys = keys.split(',')
return tuple(getattr(self, attr) for attr in keys)
attribute_tuple.get = get
def set(self,keys,values):
keys = keys.split(',')
if len(keys) != len(values):
raise ValueError('too many values to unpack (expected %d)'%len(keys))
for attr,val in zip(keys, values):
setattr(self, attr, val)
attribute_tuple.set = set
def delete(self,keys):
keys = keys.split(',')
for attr in keys:
delattr(self, attr)
attribute_tuple.delete = delete
cls.__getitem__ = attribute_tuple.get
cls.__setitem__ = attribute_tuple.set
cls.__delitem__ = attribute_tuple.delete
return cls
@attribute_tuple
class myclass:
pass
Я не думаю, что любое количество взлома '__getattr__' или' __getattribute__' вы можете получить это, потому что это против грамматики. – wim