使用在每个实例级别而不是每个类定义的属性
我想要实现的目标是这样的:
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
What I am trying to achieve is something like this:
class object:
def __init__(self):
WidthVariable(self)
print self.width
#Imagine I did this 60frames/1second later
print self.width
#output:
>>0
>>25
What I want happening (as above): When WidthVariable
- a class - is created it adds the variable width
to the object instance. This variable acts like a normal property, but in this particular case it is read-only (only the fget
variable is set). Additionally, the fget
calls a function defined in WidthVariable
which decides what width
to return.
However, I have no idea how to do this! I tried it using normal properties but I found that they only work on classes and not per instance - please note that the code I use should be similar as possible to the above (i.e. only code within the __init__
of WidthVariable
should set the width
variable, nowhere else). Also, self.width
cannot be function, because I do not what to call it like self.width()
, I want self.width
(because it keeps with the rest of the design I have).
To clarify, the complete code would be something like this:
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
正如@Jonathan所说,描述符(包括属性)是每个类的,而不是每个实例的,因此获得不同的每个实例描述符的唯一方法是让每个实例个性化自己的类。就元编程而言,这是相当浅薄和简单的;-)...:
我还显式添加
object
因为它是需要的(在 Python2.*
中,你一定要说这就是你正在使用的!!!)来使类成为新类型。永远不要再使用遗留类,它们在属性和其他方面的行为都不正确(而且为了向后兼容,它们不能——在Python 3中,遗留类最终被消灭了,所以每个类都是新式的,没有不再需要显式地从对象继承!)。现在,放置在 self.__class__.__dict__ 中的任何描述符都只会影响此一个实例,不会影响其他实例。有一点开销(每个
GottaBeMe
类,因此每个实例都有自己的__dict__
等),但没什么太可怕的。现在,满足原始请求所需的只是更改:(
还明智地重命名
object
arg 以避免践踏内置函数,并使类成为新样式,因为您应该始终使每个class new-style;-), to:没有什么太黑魔法的,如你所见!-)
Since, as @Jonathan says, descriptors (including properties) are per-class, not per-instance, the only way to get different per-instance descriptors is to have each instance individualize its own class. That's pretty shallow and easy as far as metaprogramming goes;-)...:
I'm also adding
object
explicitly because it's needed (in Python2.*
, and you do say that's what you're using!!!) to make classes new-type. Never use legacy classes any more, they don't behave correctly with respect to properties and much else besides (and for backwards compatibility they can't -- in Python 3, legacy classes have finally been annihilated so EVERY class is new-style without the requirement to explicitly inherit from object any more!).Now, any descriptor that's placed in
self.__class__.__dict__
will only affect this one instance, none other. There's a bit of overhead (eachGottaBeMe
class and therefore each instance has its own__dict__
, etc), but nothing too terrible.Now, all that's needed to satisfy the original request is to change:
(also renaming the
object
arg sensibly to avoid trampling on a built-in, and making the class new-style because you should ALWAYS make EVERY class new-style;-), to:Nothing too black-magicky, as you can see!-)
我相信我现在明白你的问题,而且我也相信你是 运气不好。
描述符(用于实现属性)必须出现在类的
__dict__
中,并且不能出现在实例的__dict__
中>。换句话说,Python 不是 Ruby!我很高兴地等待一位虔诚的 Python 元程序员的纠正,但我认为我是对的。
I believe I now understand your question, and I also believe you're out of luck.
Descriptors (which are used to implement properties) must appear in the class's
__dict__
, and cannot appear in the instance's__dict__
. In other words, Python is not Ruby!I happily await correction from a godly Python metaprogrammer, but I think I'm right.
我不明白你构建示例的方式,也不明白你所说的“普通属性”仅适用于“类”的含义。以下是创建只读属性的方法:
I don't understand the way you've constructed your example, nor do I understand what you mean about "normal properties" only working "on classes". Here's how you create a read-only property:
不太清楚你想要什么?但我假设您希望为每个实例自定义 obj.width
这是使用普通属性的简单方法,宽度属性返回每个实例回调返回的值
如果无法传递回调,我们可以将其分配给 WidthVariable,它根据实例返回宽度
Not very clear what you want? but I assume you want obj.width to be customized for each instance
Here is a easy way by using plain properties, width property returns value returned by a per instance callback
If callback can not be passed we can assign it to WidthVariable which returns width based on instance