python面試題之下面這些是什么意思:@classmethod, @staticmethod, @property?


回答背景知識

這些都是裝飾器(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黑洞網,博客園同步跟新


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM