【发布时间】:2016-03-13 12:17:53
【问题描述】:
这个问题是关于基于super() 的对象的只读问题,以及是否/如何超级可以/应该控制子类上的__setattr__。
上下文:
有没有办法编写 元类 或 descriptor 使得作为包含属性 self.read_only = True 的类的子类的所有类都不能执行子类化getattr 以“set_”开头的函数,但self.read_only = False 可以在哪里?
我在想 object.__setattr__(self, name, value) 的覆盖:
在尝试进行属性分配时调用。这就是所谓的 而不是正常的机制(即将值存储在实例中 字典)。 name 是属性名称,value 是要成为的值 分配给它。
...是正确的方向,但我怀疑我对文档的解释是否正确。
示例:
Super 符合系统设计者的意图:
class BaseMessage(object):
def __init__(self, sender, receiver, read_only=True):
self.sender = sender
self.receiver = receiver
self.read_only = read_only
def __setattr__(self, name, value):
if self.read_only:
raise AttributeError("Can't set attributes as message is read only.")
else:
# ? set attribute...(suggestion welcome)
def get_sender(self): # Is a "get" and not "set" call, so it should be callable disregarding self.read_only's value.
return self.sender
def get_receiver(self):
return self.receiver
子由对所有后果了解有限的系统扩展器制作:
class MutableMessage(BaseMessage):
def __init__(self, sender, receiver, topic, read_only=False):
super().__init__(sender=sender, receiver=receiver, read_only=read_only)
self.topic = topic
# this call should be okay as super's property is read_only=False.
def set_topic_after_init(new_topic):
self.topic = topic
class ImmutableMessage(BaseMessage):
def __init__(self, sender, receiver, topic): # read_only=True !
super().__init__(sender=sender, receiver=receiver, read_only=read_only)
self.topic = topic
# this call should fail as super's property is read_only=True.
def set_topic_after_init(new_topic):
self.topic = topic
示例说明
在MutableMessage 中,系统扩展程序明确声明 read_only 为 False,并且知道添加函数 set_topic 的后果。
在ImmutableMessage(下)中,系统扩展程序忘记声明消息应该是read_only=False,这应该导致supers __setattr__ 到raise AttributeError:
核心问题: 下面示例中所示的用法是否足以一致地应用于基于 BaseMessage 类的所有类?
认为我是元编程的新手。因此,对我的示例的任何误解和/或扩展和更正的解释将是至高无上的。我了解hierarchy [1],但不了解python在继承过程中在幕后做了什么。
谢谢...
[1]:层次结构
Python 用于属性的搜索顺序如下:
__getattribute__和__setattr__- 数据描述符,如属性
- 来自对象
__dict__的实例变量- 非数据描述符(如方法)和其他类变量
__getattr__由于
__setattr__排在第一位,如果你有一个,你需要让它变得聪明,除非你想让它处理你班级的所有属性设置。它可以通过两种方式中的任何一种变得聪明。一个。使其仅处理特定的集合属性,或者,
b.让它处理除某些属性之外的所有属性。
如果您不希望它处理,请致电
super().__setattr__。
相关问题:
【问题讨论】:
标签: python-3.x inheritance setattr