使用在每个实例级别定义的属性而不是每个类
-
06-07-2019 - |
题
我想要实现的是这样的:
class object:
def __init__(self):
WidthVariable(self)
print self.width
#Imagine I did this 60frames/1second later
print self.width
#output:
>>0
>>25
我想要发生什么(如上所述):当 WidthVariable
- 一个类 - 被创建时,它将变量 width
添加到对象实例 。此变量的作用类似于普通属性,但在此特定情况下,它是只读的(仅设置 fget
变量)。此外, fget
调用 WidthVariable
中定义的函数,该函数决定返回的 width
。
但是,我不知道该怎么做!我尝试使用普通属性,但我发现它们只适用于类而不是每个实例 - 请注意我使用的代码应尽可能与上面的代码相似(即只有 __ init __
中的代码) WidthVariable
应该设置 width
变量,而不是其他地方)。另外, self.width
不能是函数,因为我不像 self.width()
那样调用它,我想 self.width
(因为它与我的其他设计保持一致)。
为了澄清,完整的代码将是这样的:
class MyObject:
def __init__(self)
WidthVariable(self)
print self.width
class WidthVariable:
def __init__(self, object)
object.width = property(self.get_width)
def get_width(self):
value = #do_stuff
return value #The Value
#output:
>>25 #Whatever the Value was
解决方案
因为正如@Jonathan所说,描述符(包括属性)是每个类而不是每个实例,获得不同的每个实例描述符的唯一方法是让每个实例个性化它自己的类。就元编程而言,这是非常浅薄和容易的; - )......:
class Individualistic(object_or_whatever_bases):
def __init__(self, whatever_args):
self.__class__ = type('GottaBeMe', (self.__class__, object), {})
# keep rocking...!-)
我还明确地添加了 object
,因为它需要(在Python 2。*
中,你确实说这是你正在使用的东西!!!)班级新型。永远不再使用遗留类,它们在属性方面表现不正确以及其他许多方面(并且为了向后兼容性,它们不能 - 在Python 3中,遗留类最终被消灭所以每个类都是新类型没有要求明确继承自对象!)。
现在,放在 self .__ class __.__ dict __
中的任何描述符只会影响这一个实例,而不会影响其他实例。有一些开销(每个 GottaBeMe
类,因此每个实例都有自己的 __ dict __
等),但没什么可怕的。
现在,满足原始请求所需的只是改变:
class WidthVariable:
def __init__(self, object)
object.width = property(self.get_width)
(还明智地重命名 object
arg以避免践踏内置,并使类成为新式,因为你应该总是让每个类都成为新式;-),以: / p>
class WidthVariable(object):
def __init__(self, obj)
obj.__class__.width = property(self.get_width)
正如你所看到的,没有什么太黑的魔法了! - )
其他提示
我不明白你构建你的例子的方式,也不理解你的意思和“正常属性”。只能在“课堂上”工作。以下是创建只读属性的方法:
class Foo(object):
# create read-only property "rop"
rop = property(lambda self: self._x)
def __init__(self):
self._x = 0
def tick(self):
self._x += 1
f = Foo()
print f.rop # prints 0
f.tick()
f.tick()
print f.rop # prints 2
f.rop = 4 # this will raise AtributeError
我相信我现在理解你的问题,我也相信你是运气不好。
对于新式类,隐式 特殊方法的调用是 只保证正常工作 在对象’ s类型上定义,而不是在 对象’ s实例字典。
描述符(用于实现属性)必须出现在类的 __ dict __
中,并且不能出现在实例的 __ dict__中代码>。换句话说,Python不是Ruby!
我高兴地等待着一位虔诚的Python元程序员的纠正,但我认为我是对的。
不是很清楚你想要什么?但我假设您希望为每个实例定制obj.width 这是一种使用普通属性的简单方法,每个实例回调返回的width属性返回值
class MyClass(object):
def __init__(self, callback):
self.callback = callback
def get_width(self):
return self.callback()
width = property(get_width)
def w1(): return 0
def w2(): return 25
o1 = MyClass(w1)
o2 = MyClass(w2)
print o1.width
print o2.width
如果无法传递回调,我们可以将其分配给WidthVariable,它根据实例返回宽度
class MyClass(object):
def __init__(self):
self.callback = WidthVariable(self)
def get_width(self):
return self.callback()
width = property(get_width)
class WidthVariable(object):
def __init__(self, obj):
self.obj = obj
def __call__(self):
return hash(self.obj)
o1 = MyClass()
o2 = MyClass()
print o1.width
print o2.width