В моих начинаниях как ученик-питон я недавно застрял в нечетном (с моей точки зрения) поведении, если я пытался работать с атрибутами класса. Я не жалуюсь, но буду благодарен за некоторые полезные комментарии, чтобы пролить свет на эту проблему.python: атрибут класса/наследование с полиморфизмом?
Чтобы уменьшить сложный вопрос в более лаконичный вопрос я бы сформулировал это следующим образом:
Что такое «вещий» способ гарантировать, что класс-атрибут ведет себя больше как статические переменный в дереве наследования?
Мне кажется, что атрибут класса ведет себя как значение «копировать по чтению» по умолчанию с полиморфными характеристиками. Пока я выполняю операции «только для чтения», он остается «singleton», , но как только я получаю доступ к атрибуту class с назначением через производный класс или экземпляр, он превращается в новую ссылку, теряющую отношение к унаследованная базовая ссылка.
(Он обладает надежным потенциалом для некоторых interessting функций, но вы должны понять его принять его, так что некоторое представление высоко ценится.)
class A(object):
classvar = 'A'
def setclassvar(self, value):
A.classvar = value
def __str__(self):
return "%s id(%s) " %(A.classvar, hex(id(A.classvar))[2:-1].upper())
class A1(A):
pass
class B(object):
classvar = 'B'
def setclassvar(self, value):
self.__class__.classvar = value
def __str__(self):
cvar = self.__class__.classvar
return "%s id(%s) " %(cvar, hex(id(cvar))[2:-1].upper())
class B1(B):
def setclassvar(self, value):
self.__class__.classvar = value
a, a1 = A(), A1()
a1.setclassvar('a')
print "new instance A: %s" %a
print "new instance A1: %s" %a
b, b1 = B(), B1()
b1.setclassvar('bb')
print "new instance B: %s" %b
print "new instance B1: %s" %b1
a1.setclassvar('aa')
print "new value a1: %s" %a
print "new value a: %s" %a
a1.classvar = 'aaa'
print "direct access a1: %s id(%s)" %(a1.classvar, hex(id(a1.classvar))[2:-1].upper())
print "method access a1: %s" %a1
print "direct access a: %s" %a
производит следующее:
new instance A: a id(B73468A0) new instance A1: a id(B73468A0) new instance B: B id(B73551C0) new instance B1: bb id(AD1BFC) new value a1: aa id(AD1BE6) new value a: aa id(AD1BE6) direct access a1: aaa id(A3A494) method access a1: aa id(AD1BE6) direct access a: aa id(AD1BE6)
Таким образом, либо прямой (назначающий) доступ object.classvar
, либо опосредованный через self.__class__.classvar
не являются такой же, как BASECLASS.classvar
.
Является ли это проблемой сферы или что-то совсем другое.
Ждем ваших ответов и спасибо вперёд. :-)
Edit: Был ответ в течение очень короткого промежутка времени предполагая использование класса-дескрипторов, как: How to make a class property?.
Unfortunatly, что не похоже на работу:
class Hotel(Bar):
def __init__(self):
Hotel.bar += 1
hotel = Hotel()
assert hotel.bar == 51
assert hotel.bar == foo.bar
2-е утверждение не! hotel.bar не ссылается на тот же объект, что и foo.bar
, и hotel.bar
ссылки somethin other then Hotel.bar!
второй Edit: я вполне в курсе, что одноэлементные считаются «антипаттерн» и я не намерен их использовать (extensivly). Поэтому я не упоминал их в вопросе-тиле. Тем не менее, есть много решений, которые обсуждают и предоставляют решения с синглтонами и о них, мой вопрос остается: почему переменная класса легко отделяет ссылку? Рубин ведет себя больше, как он чувствует себя естественно для меня: http://snippets.dzone.com/posts/show/6649
Ищите Python Singleton. (а) на это был дан ответ, и (б) обычно очень сложно попытаться создать Синглтонов. http://stackoverflow.com/search?q=python+singleton –
Возможный дубликат [Создание синглета в python] (http://stackoverflow.com/questions/6760685/creating-a-singleton-in-python) –
Меня не интересует «антипаттерн», поэтому, пожалуйста, несите меня в этом вопросе, но вы избегаете пули проблемы с наследством. Все рассмотренные мной решения не касались полиморфной характеристики задания, которое убивает исходную ссылку. Ruby, с другой стороны, делает то, что кажется мне более «естественным» (но, скорее, не для других): http://snippets.dzone.com/posts/show/6649. Поэтому я предполагаю, что это проблема с областью имен или тому подобное, но им все еще интересно. –