python面试题之下面这些是什么意思:@classmethod, @staticmethod, @property?
程序员文章站
2022-07-02 12:52:03
回答背景知识 这些都是装饰器(decorator)。装饰器是一种特殊的函数,要么接受函数作为输入参数,并返回一个函数,要么接受一个类作为输入参数,并返回一个类。 @标记是语法糖(syntactic sugar),可以让你以简单易读得方式装饰目标对象。 @my_decorator def my_fun ......
回答背景知识
这些都是装饰器(decorator)。装饰器是一种特殊的函数,要么接受函数作为输入参数,并返回一个函数,要么接受一个类作为输入参数,并返回一个类。
@标记是语法糖(syntactic sugar),可以让你以简单易读得方式装饰目标对象。
@my_decorator def my_func(stuff): do_things is equivalent to def my_func(stuff): do_things my_func = my_decorator(my_func)
你可以在本网站上找到介绍装饰器工作原理的教材。
真正的答案
@classmethod
, @staticmethod
和@property
这三个装饰器的使用对象是在类中定义的函数。下面的例子展示了它们的用法和行为:
class myclass(object): def __init__(self): self._some_property = "properties are nice" self._some_other_property = "very nice" def normal_method(*args,**kwargs): print "calling normal_method({0},{1})".format(args,kwargs) @classmethod def class_method(*args,**kwargs): print "calling class_method({0},{1})".format(args,kwargs) @staticmethod def static_method(*args,**kwargs): print "calling static_method({0},{1})".format(args,kwargs) @property def some_property(self,*args,**kwargs): print "calling some_property getter({0},{1},{2})".format(self,args,kwargs) return self._some_property @some_property.setter def some_property(self,*args,**kwargs): print "calling some_property setter({0},{1},{2})".format(self,args,kwargs) self._some_property = args[0] @property def some_other_property(self,*args,**kwargs): print "calling some_other_property getter({0},{1},{2})".format(self,args,kwargs) return self._some_other_property o = myclass() # 未装饰的方法还是正常的行为方式,需要当前的类实例(self)作为第一个参数。 o.normal_method # <bound method myclass.normal_method of <__main__.myclass instance at 0x7fdd2537ea28>> o.normal_method() # normal_method((<__main__.myclass instance at 0x7fdd2537ea28>,),{}) o.normal_method(1,2,x=3,y=4) # normal_method((<__main__.myclass instance at 0x7fdd2537ea28>, 1, 2),{'y': 4, 'x': 3}) # 类方法的第一个参数永远是该类 o.class_method # <bound method classobj.class_method of <class __main__.myclass at 0x7fdd2536a390>> o.class_method() # class_method((<class __main__.myclass at 0x7fdd2536a390>,),{}) o.class_method(1,2,x=3,y=4) # class_method((<class __main__.myclass at 0x7fdd2536a390>, 1, 2),{'y': 4, 'x': 3}) # 静态方法(static method)中除了你调用时传入的参数以外,没有其他的参数。 o.static_method # <function static_method at 0x7fdd25375848> o.static_method() # static_method((),{}) o.static_method(1,2,x=3,y=4) # static_method((1, 2),{'y': 4, 'x': 3}) # @property是实现getter和setter方法的一种方式。直接调用它们是错误的。 # “只读”属性可以通过只定义getter方法,不定义setter方法实现。 o.some_property # 调用some_property的getter(<__main__.myclass instance at 0x7fb2b70877e8>,(),{}) # 'properties are nice' # “属性”是很好的功能 o.some_property() # calling some_property getter(<__main__.myclass instance at 0x7fb2b70877e8>,(),{}) # traceback (most recent call last): # file "<stdin>", line 1, in <module> # typeerror: 'str' object is not callable o.some_other_property # calling some_other_property getter(<__main__.myclass instance at 0x7fb2b70877e8>,(),{}) # 'very nice' # o.some_other_property() # calling some_other_property getter(<__main__.myclass instance at 0x7fb2b70877e8>,(),{}) # traceback (most recent call last): # file "<stdin>", line 1, in <module> # typeerror: 'str' object is not callable o.some_property = "groovy" # calling some_property setter(<__main__.myclass object at 0x7fb2b7077890>,('groovy',),{}) o.some_property # calling some_property getter(<__main__.myclass object at 0x7fb2b7077890>,(),{}) # 'groovy' o.some_other_property = "very groovy" # traceback (most recent call last): # file "<stdin>", line 1, in <module> # attributeerror: can't set attribute o.some_other_property # calling some_other_property getter(<__main__.myclass object at 0x7fb2b7077890>,(),{})
本文首发于python黑洞网,博客园同步跟新