如何根据条件快速禁用类实例中的所有方法?我天真的解决方案是使用__getattr__
重写,但是当函数名已经存在时,就不会调用它。在
class my():
def method1(self):
print 'method1'
def method2(self):
print 'method2'
def __getattr__(self, name):
print 'Fetching '+str(name)
if self.isValid():
return getattr(self, name)
def isValid(self):
return False
if __name__ == '__main__':
m=my()
m.method1()
实际上,您要做的等效操作实际上是重写
__getattribute__
,它将为每个属性访问调用。除此之外,还要注意:根据every的定义,这包括对__getattribute__
自身主体内的self.isValid
的调用,因此您必须使用一些迂回的路径来访问该属性(type(self).isValid(self)
应该可以工作,例如,因为它从类而不是从实例获取属性)。在这指向了一个可怕的术语混乱:这是不是禁用“来自类的方法”,而是来自一个实例,尤其与
classmethods
无关。如果您确实希望在类的基础上而不是在实例的基础上以类似的方式工作,您需要创建一个自定义元类,并重写元类上的__getattribute__
(这是当您在标题和文本中要求访问类的属性时调用的元类,而不是像您实际所做的那样在实例上访问属性时调用的元类,这是迄今为止比较正常和常见的案例)。在编辑:一种完全不同的方法可能是使用一种特殊的python路径来实现
State
设计模式:类交换。E、 g.:只要您可以适当地调用}是找到所有对象方法的地方,所以通过切换它,您可以整体地切换在给定时间存在于对象上的方法集。但是,如果您绝对坚持必须“及时”执行有效性检查,也就是说,在查找对象的方法的那一刻,这就行不通了。在
setValid
,这样对象的__class__
被适当地切换,这是非常快速和简单的本质上,对象的{在这和
^{pr2}$__getattribute__
之间的一个中间方法是引入一个额外的间接层次(通常认为这是所有问题的解决方案;-),大致如下:这比
__getattribute__
更惯用,因为它依赖于这样一个事实,即__getattr__
只为在其他方式中找不到的属性调用,因此对象可以在其__dict__
中保存正常状态(数据),并且访问这些状态时不会产生任何大的开销;只有方法调用才支付indirection的额外开销。如果任何状态需要在无效对象上保持可访问状态,_Valid
类实例可以将部分或全部状态保持在各自的self._actualobject
中(因此,无效状态禁用方法,但不能访问数据属性;如果需要,从Q中不清楚,但是这种方法提供了一种免费的额外可能性)。这个习惯用法比__getattribute__
更不容易出错,因为可以在方法中更直接地访问状态(而不触发有效性检查)。在如前所述,该解决方案创建一个循环引用循环,这可能会在垃圾收集方面带来一些开销。{如果一个最简单的问题是从一个Python应用程序的一个最简单的模块中删除循环},如果这是一个最简单的问题,那么通常使用循环的方法。 (例如,使属性的对象的弱引用)。在
_Valid
类实例的_actualobject
属性成为对将该实例作为其^{相关问题 更多 >
编程相关推荐