Python 实现getattr/setattr的类中的普通属性
我有这个:Python 实现getattr/setattr的类中的普通属性,python,Python,我有这个: class MySession: def __init__(self, session): session['my-data'] = {} # my data is here self._session = session def __getattr__(self, name): return self._session['my-data'][name] def __setattr__(self, nam
class MySession:
def __init__(self, session):
session['my-data'] = {} # my data is here
self._session = session
def __getattr__(self, name):
return self._session['my-data'][name]
def __setattr__(self, name, value):
my_data = self._session['my-data']
my_data[name] = value
self._session['my-data'] = my_data
obj = MySession({})
obj.x = 3
基本上,我想用对象属性access封装对会话(子)字典的访问。但我不能这样做,因为这会导致无限递归,我猜是因为这样做:
self._session = session
调用setattr,setattr调用getattr,getattr调用getattr,等等
如何在实现getattr/setattr的类中预初始化某些(普通)属性?您可以先初始化,然后更改setter-getter:
def __init__(self, session):
session['my-data'] = {}
self._session = session
self.__setattr__ = self._setattr
self.__getattr__ = self._getattr
假设
self.\u setattr
和self.\u getattr
当然是实现的:)只对普通属性字典中不存在的属性调用\u getattr\u
方法\uuuuu setattr\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。如果可以在\uuu init\uuuu
中正确设置\u会话
属性,则不必担心其他方法中的任何问题
要添加属性而不运行任何递归,请使用super(MySession,self)。\uuuuu setattr\uuuuu
调用从object
继承的方法的版本(在Python 2中,您应该始终从object
继承,使您的类成为一个新样式的类,在Python 3中,它是默认的)。您也可以直接调用对象。\uuuu setattr\uuuu
,但如果最终使用多重继承,则使用super
会更好
class MySession(object):
def __init__(self, session):
session['my-data'] = {}
super(MySession, self).__setattr__("_session", session) # avoid our __setattr__
def __getattr__(self, name):
return self._session['my-data'][name] # this doesn't recurse if _session exists
def __setattr__(self, name, value):
my_data = self._session['my-data']
my_data[name] = value
self._session['my-data'] = my_data
这会导致相同的无限递归:self.session再次调用getattrGreat,谢谢。关于setattr的实现:我知道这很尴尬,但这与django中会话的工作方式有关:设置子键不会更新会话。这是一种常见的django gotcha<代码>类型错误:super()至少接受1个参数(给定0)
。我使用的是Python2.7Ah,我假设您使用的是Python3,因为您的类缺少object
。在Python2中,您肯定希望这样做(或者无论您如何称呼它,super
都无法工作)。您还需要为super
调用提供参数,因为Python 2的版本不能像Python 3那样自动推断类。我已经更新了Python 2的答案,并将\uuuu setattr\uuuu
实现恢复到您所说的方式。不幸的是,它不起作用_未使用getattr。这的确很奇怪。