python-靜態方法staticmethod、類方法classmethod、屬性方法property

來源:互聯網
上載者:User

標籤:檢查   工具包   圖片   index   attrs   png   return   set   舉例   

 Python的方法主要有3個,即靜態方法(staticmethod),類方法(classmethod)和執行個體方法

12345678910111213141516 def foo(x):    print "executing foo(%s)"%(x)  class A(object):    def foo(self,x):        print "executing foo(%s,%s)"%(self,x)      @classmethod    def class_foo(cls,x):        print "executing class_foo(%s,%s)"%(cls,x)      @staticmethod    def static_foo(x):        print "executing static_foo(%s)"%x  a=A()

這個self和cls是對類或者執行個體的綁定,對於一般的函數來說我們可以這麼調用foo(x),這個函數就是最常用的,它的工作跟任何東西(類,執行個體)無關.對於執行個體方法,我們知道在類裡每次定義方法的時候都需要綁定這個執行個體,就是foo(self, x),為什麼要這麼做呢?因為執行個體方法的調用離不開執行個體,我們需要把執行個體自己傳給函數,調用的時候是這樣的a.foo(x)(其實是foo(a, x)).類方法一樣,只不過它傳遞的是類而不是執行個體,A.class_foo(x).注意這裡的self和cls可以替換別的參數,但是python的約定是這倆,還是不要改的好.

對於靜態方法其實和普通的方法一樣,不需要對誰進行綁定,唯一的區別是調用的時候需要使用a.static_foo(x)或者A.static_foo(x)來調用.

 

\ 執行個體方法 類方法 靜態方法
a = A() a.foo(x) a.class_foo(x) a.static_foo(x)
A 不可用 A.class_foo(x) A.static_foo(x)

 

類的普通方法

class Animal(object):    def __init__(self,name):        self.name = name    def intro(self):        print(‘there is a %s‘%(self.name))cat = Animal(‘cat‘)cat.intro()
  • 靜態類方法
class Animal(object):    def __init__(self,name):        self.name = name    @staticmethod    def intro(self):        print(‘there is a %s‘%(self.name))cat = Animal(‘cat‘)cat.intro()
  • 加上裝飾器後運行會報錯,原因是方法變為一個普通函數,脫離的與類的關係,不能引用建構函式中的變數了。 

使用情境舉例:python內建方法os中的方法,可以直接使用的工具包,跟類沒關係。

class Animal(object):    def __init__(self,name):        self.name = name    @classmethod    def intro(self):        print(‘there is a %s‘%(self.name))cat = Animal(‘cat‘)cat.intro()
  • 報錯資訊 

如果換成

class Animal(object):    name = ‘cat‘    def __init__(self,name):        self.name = name    @classmethod    def intro(self):        print(‘there is a %s‘%(self.name))cat = Animal(‘cat‘)cat.intro()
  • 可以正常運行。 

結論:類方法只能調用類變數,不能調用執行個體變數

屬性方法@property 把一個方法變為(偽裝成)類屬性。因為類屬性的實質是一個類變數,使用者可以調用變數就可以修改變數。某些特定情境要限制使用者行為,就用到靜態方法。 
@property廣泛應用在類的定義中,可以讓調用者寫出簡短的代碼,同時保證對參數進行必要的檢查,這樣,程式運行時就減少了出錯的可能性。(摘自廖雪峰的部落格)

class Animal(object):    def __init__(self,name):        self.name = name    @property    def intro(self,food):        print(‘there is a %s eating %s‘%(self.name,food))cat = Animal(‘cat‘)cat.intro()
  • 報錯:

     

  • 方法不能正常調用。如果要調用,如下:
cat.intro
  • 是這樣的話,方法就沒辦法單獨傳入參數。如果要傳入參數,如下:
class Animal(object):    def __init__(self,name):        self.name = name    @property    def intro(self):        print(‘there is a %s eating %s‘%(self.name,food))    @intro.setter    def intro(self,food):        passcat = Animal(‘cat‘)cat.intro
  • cat.intro還有其他動作getter deleter等等。
一:staticmethod代碼如下:
class Singleton(object):    instance = None    def __init__(self):        raise SyntaxError(‘can not instance, please use get_instance‘)    @staticmethod    def get_instance():        if Singleton.instance is None:            Singleton.instance = object.__new__(Singleton)        return Singleton.instancea = Singleton.get_instance()b = Singleton.get_instance()print(‘a id=‘, id(a))print(‘b id=‘, id(b))
該方法的要點是在__init__拋出異常,禁止通過類來執行個體化,只能通過靜態get_instance函數來擷取執行個體;因為不能通過類來執行個體化,所以靜態get_instance函數中可以通過父類object.__new__來執行個體化。 二:classmethod和方法一類似,代碼: 
class Singleton(object):    instance = None    def __init__(self):        raise SyntaxError(‘can not instance, please use get_instance‘)    @classmethod    def get_instance(cls):        if Singleton.instance is None:            Singleton.instance = object.__new__(Singleton)        return Singleton.instancea = Singleton.get_instance()b = Singleton.get_instance()print(‘a id=‘, id(a))print(‘b id=‘, id(b))
該方法的要點是在__init__拋出異常,禁止通過類來執行個體化,只能通過靜態get_instance函數來擷取執行個體;因為不能通過類來執行個體化,所以靜態get_instance函數中可以通過父類object.__new__來執行個體化。 三:類屬性方法和方法一類似, 代碼:
class Singleton(object):    instance = None    def __init__(self):        raise SyntaxError(‘can not instance, please use get_instance‘)    def get_instance():        if Singleton.instance is None:            Singleton.instance = object.__new__(Singleton)        return Singleton.instancea = Singleton.get_instance()b = Singleton.get_instance()print(id(a))print(id(b))
該方法的要點是在__init__拋出異常,禁止通過類來執行個體化,只能通過靜態get_instance函數來擷取執行個體;因為不能通過類來執行個體化,所以靜態get_instance函數中可以通過父類object.__new__來執行個體化。 四:__new__

常見的方法, 代碼如下:

 

class Singleton(object):    instance = None    def __new__(cls, *args, **kw):        if not cls.instance:            # cls.instance = object.__new__(cls, *args)            cls.instance = super(Singleton, cls).__new__(cls, *args, **kw)        return cls.instancea = Singleton()b = Singleton()print(id(a))print(id(b))

 

 

五:裝飾器

代碼如下:

 

def Singleton(cls):    instances = {}    def getinstance():        if cls not in instances:            instances[cls] = cls()        return instances[cls]    return getinstance@Singletonclass MyClass:    passa = MyClass()b = MyClass()c = MyClass()print(id(a))print(id(b))print(id(c))

 

 

六:元類python2版:
class Singleton(type):    def __init__(cls, name, bases, dct):        super(Singleton, cls).__init__(name, bases, dct)        cls.instance = None    def __call__(cls, *args):        if cls.instance is None:            cls.instance = super(Singleton, cls).__call__(*args)        return cls.instanceclass MyClass(object):    __metaclass__ = Singletona = MyClass()b = MyClass()c = MyClass()print(id(a))print(id(b))print(id(c))print(a is b)print(a is c)
或者:
class Singleton(type):    def __new__(cls, name, bases, attrs):        attrs["_instance"] = None        return super(Singleton, cls).__new__(cls, name, bases, attrs)    def __call__(cls, *args, **kwargs):        if cls._instance is None:            cls._instance = super(Singleton, cls).__call__(*args, **kwargs)        return cls._instanceclass Foo(object):    __metaclass__ = Singletonx = Foo()y = Foo()print(id(x))print(id(y))
 python3版:
class Singleton(type):    def __new__(cls, name, bases, attrs):        attrs[‘instance‘] = None        return super(Singleton, cls).__new__(cls, name, bases, attrs)    def __call__(cls, *args, **kwargs):        if cls.instance is None:            cls.instance = super(Singleton, cls).__call__(*args, **kwargs)        return cls.instanceclass Foo(metaclass=Singleton):    passx = Foo()y = Foo()print(id(x))print(id(y))
 七:名字覆蓋代碼如下:
class Singleton(object):    def foo(self):        print(‘foo‘)    def __call__(self):        return selfSingleton = Singleton()Singleton.foo()a = Singleton()b = Singleton()print(id(a))print(id(b))

 

python-靜態方法staticmethod、類方法classmethod、屬性方法property

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.