分享

python中:如何让classmethod只允许使用用类对象来调用

 java_laq小馆 2013-10-24

如何让classmethod只允许使用用类对象来调用


原blog链接:如何让classmethod只允许使用用类对象来调用


我们知道在python中使用classmethod可以把一个方法处理为类方法,这样就可以直接使用类对象来调用它了。但是,它也有一个不算问题的问题,就是也可以使用实例来调用,比如:

  1. class A(object):  
  2.     @classmethod  
  3.     def p(cls):  
  4.         print 'call p()'  
  5. a = A()  
  6. A.p()  
  7. a.p()  
但 是有时,我们可能希望这个方法只能被类对象来调用,而不能使用实例来调用。为什么会有这样的需求?举一个例子,数据库操作中,Model有 delete()和remove()方法。其中delete()是用在实例上的,删除一个记录,而remove()是定义为classmethod的,删 除整个表的所有记录。但是有时在实例上误写为record.remove(),这样的结果是会将表全部删除,而不是只删除这一条记录。所以这里 remove()具有一定的危险性。所以我想有这么一种限制,即类方法只能用类对象来调用。当然,并不是所有的类方法都需要这样,只对有破坏性或危险性的 方法这样处理。那么怎么做呢?可以通过写了一个descriptor的类,可以干这件事,同时它可以像classmethod一样作为decorator 来使用。代码如下:

  1. class classonlymethod(object):  
  2.     """ 
  3.     Use to limit the class method can only be called via class object, but not instance 
  4.     object 
  5.  
  6.     >>> class A(object): 
  7.     ...     @classonlymethod 
  8.     ...     def p(cls): 
  9.     ...         print 'call p()' 
  10.     >>> A.p() 
  11.     call p() 
  12.     >>> a = A() 
  13.     >>> try: 
  14.     ...     a.p()         
  15.     ... except Exception as e: 
  16.     ...     print e 
  17.     Method p can only be called with class object 
  18.     """  
  19.   
  20.     def __init__(self, func):  
  21.         self._func = func  
  22.   
  23.     def __get__(self, model_instance, model_class):  
  24.         if model_instance is not None:  
  25.             raise AttributeError("This method can only be called with class object.")  
  26.         return super(classonlymethod, self).__get__(model_instance, model_class)  
它使用了descriptor的特性,能过定义 __get__ 方法来区分类对象调用还是实例对象调用。


关于descriptor,可以参考:http://docs./2/howto/descriptor.html

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多