2 имени для одного и того же атрибута

Я хотел бы знать, есть ли способ «связать» два атрибута класса или дать 2 имени одному и тому же атрибуту?

Например, я фактически работаю над скриптом, который создает треугольник из данных, данных пользователями. Мой треугольник – ABC. Стороны этого треугольника – AB, BC и CA. Таким образом, треугольник имеет эти 3 атрибута (self.AB, self.BC, self.CA). Но AB = BA, поэтому я хотел бы разрешить пользователям print myInstance.BA вместо print myInstance.AB .

Поэтому я решил создать атрибут self.AB и свойство BA (которые возвращают self.AB). Это отлично работает, когда я пытаюсь print myInstance.BA вместо print myInstance.AB но я жадный …

Я также хотел бы разрешить пользователям делать myInstance.BA = 5 вместо myInstance.AB = 5 а при этом также редактировать атрибут AB.

Есть ли способ сделать это?

2 Solutions collect form web for “2 имени для одного и того же атрибута”

Свойства Python могут иметь сеттеры. Так что все, что вам нужно, это

 class Foo(object): @property def BA(self): return self.AB @BA.setter def BA(self, value): self.AB = value 

И, не обращая внимания на ответ @ amccormack, если вы можете положиться на порядок имен атрибутов, это работает более обобщенно, например, для ребер bc, cd:

  class Foo(object): def __init__(self): self.ab = 100 def __getattr__(self, name): return getattr(self, "".join(sorted(name))) def __setattr__(self, name, value): super(Foo, self).__setattr__("".join(sorted(name)), value) f = Foo() print f.ba f.ba = 200 print f.ba 

Один из способов сделать это – сохранить ваши стороны в пользовательской реализации словаря, как описано в этом SO-ответе .

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

То, что мы сделали, это изменить функцию поиска хэша, чтобы до того, как словарь ищет ключ, он сортирует ключ. Поскольку ключ сортируется, ba становится ab и т. Д. Сортировка происходит в функции SideDict классе SideDict .

 import collections class TransformedDict(collections.MutableMapping): """A dictionary that applies an arbitrary key-altering function before accessing the keys""" def __init__(self, *args, **kwargs): self.store = dict() self.update(dict(*args, **kwargs)) # use the free update to set keys def __getitem__(self, key): return self.store[self.__keytransform__(key)] def __setitem__(self, key, value): self.store[self.__keytransform__(key)] = value def __delitem__(self, key): del self.store[self.__keytransform__(key)] def __iter__(self): return iter(self.store) def __len__(self): return len(self.store) def __keytransform__(self, key): return key class SideDict(TransformedDict): def __keytransform__(self, key): return ''.join(sorted(key)) side=SideDict() print 'assign 3 to abc' side['abc']=3 print "side['abc']", side['abc'] print 'assign 5 to abc' side['bac']=5 print "side['abc']", side['abc'] print "side['bca']", side['bca'] 

Выполнение этого кода дает:

 assign 3 to abc side['abc'] 3 assign 5 to abc side['abc'] 5 side['bca'] 5 
  • Добавление настраиваемого фильтра Jinja2 в GAE 1.6.0
  • TypeError: может только список конкатенации (а не «str») в список
  • TemplateNotFound: index.html с Google App Engine и Jinja2
  • Как выстроить текст из python в столбцы моего терминала?
  • Правильное использование os.path и os.join
  • Свойства класса и __setattr__
  • Пустой ответ на Facebook Graph
  • Определить выражение лямбда, которое вызывает исключение
  • Python - лучший язык программирования в мире.