python:class attribute/variable inheritance with polymorphism?
在我的endeavours as a Python学徒recently at some奇迷住了我(我从点视图)的行为,如果我工作与类的属性。我会complaining not,but to some一些帮助意见appreciate"这个问题的光网络。P></
为减少在复合物更简明的问题:它会制定这样P></
"语言"是is the Way to确保类的属性,类静态变量behaves黑莓在继承树中安?P></
我似乎像一个behaves级属性默认值"copy with polymorphic在线读"的特点。"只要我只读存储器的操作","单身"stays恩but as the快,当接入级属性指派一类与安审茶源或在它morphed into the reference to the inherited松关系的基本参考。P></
它有潜在的(和有些有趣的特点,but it to You have to理解拥抱它,我知道appreciated is some Insight)高度。P></
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | 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 |
produces下面:P></
1
2
3
4
5
6
7
8
9 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)
我知道(或者直接接入
这是在不同的问题totaly扫帚或东西。P></
谢谢你的答案,看在前馈和前馈。:-)P></
编辑:there was an回答的很短的时间suggesting for the of descriptors类使用类:如何使类的属性?。P></
我不unfortunatly似乎工作:P></
1 2 3 4 5 6 7 | class Hotel(Bar): def __init__(self): Hotel.bar += 1 hotel = Hotel() assert hotel.bar == 51 assert hotel.bar == foo.bar |
在第二assertion失败!不hotel.bar the same as
2编辑:我是单身,那么事情考虑感知安"antipattern"和不打算使用them to(广泛)。值得一提的therefore them in the question不-题目。即使我有许多discussing提供解决方案和解决方案是与单身和about,我的问题:为什么我在stays级变量的参考easily detach知道吗?红宝石behaves黑莓什么感觉自然的方式对我snippets.dzone.com:http://///6649 show postsP></
1 | a1.classvar = 'aaa' |
这不是对类变量的"引用"。
这是对象"a1"中的新实例变量。
像
像
当它出现在赋值的左侧时,实例变量("classvar")只在引用的对象("a")上创建。没有通过父命名空间搜索来解析名称,因为没有要解析的内容。它正在被创建。
如果实现很难解释,那是个坏主意。
在本例中,为了复杂起见,我将包含一个实现,因为这是我在Python中喜欢的一种棘手的事情。
因此,下面的代码片段在某种程度上滥用了闭包来设计一个满足O.P.需求的类修饰器:一个在派生类中读写时保持"统一"的类变量。
另外,作为一个额外的好处,我将属性包装在一个描述符中,这使得属性在实例中是不可更改的——所以每当写入属性时——在原始类的子类或子类的实例中,类属性都会得到适当的更新。
正如python的zen所说:"如果实现很难解释,那是一个坏主意"——我认为我不可能遇到更困难的事情——我们这里讨论的是范围动态生成的元类。它将起作用,但它释放了这是"非对称"代码,因为由于类、元类、闭包和描述符机制的大量使用,它非常神秘。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | def SingletonAttrs(**names): keys = names.keys() def class_decorator(cls): class Meta(type): def __getattribute__(cls, attr): if attr in keys: return type.__getattribute__(owner_cls, attr) return type.__getattribute__(cls, attr) def __setattr__(cls, attr, value): if attr in keys: class Wrapper(object): def __init__(self, value): self.__set__(None, value) __set__ = lambda self, instance, value: setattr(owner_cls,"__" + attr, value) __get__ = lambda self, instance, owner: type.__getattribute__(owner_cls,"__" + attr) return type.__setattr__(owner_cls, attr, Wrapper(value)) return type.__setattr__(cls, attr, value) owner_cls = Meta(cls.__name__, cls.__bases__, cls.__dict__.copy()) for key in keys: setattr(owner_cls, key, names[key]) return owner_cls return class_decorator if __name__ =="__main__": @SingletonAttrs(a="value 1", b="value 2") class Test(object): pass class TestB(Test): pass t = Test() print t.a print t.b tb = TestB() tb.a ="value 3" print Test.a |