<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                在前面幾節討論類的時候,經常要將類實例化,然后通過實例來調用類的方法(函數)。在此,把前面經常做的這類事情概括一下: * 方法是類內部定義函數,只不過這個函數的第一個參數是self。(可以認為方法是類屬性,但不是實例屬性) * 必須將類實例化之后,才能通過實例調用該類的方法。調用的時候在方法后面要跟括號(括號中默認有self參數,但是不寫出來。) 通過實例調用方法(在前面曾用了一個不嚴謹的詞語:實例方法),我們稱這個方法**綁定**在實例上。 ## [](https://github.com/qiwsir/StarterLearningPython/blob/master/210.md#調用綁定方法)調用綁定方法 前面一直在這樣做。比如: ~~~ class Person(object): def foo(self): pass ~~~ 如果要調用Person.foo()方法,必須: ~~~ pp = Person() #實例化 pp.foo() ~~~ 這樣就實現了方法和實例的綁定,于是通過`pp.foo()`即可調用該方法。 ## [](https://github.com/qiwsir/StarterLearningPython/blob/master/210.md#調用非綁定方法)調用非綁定方法 在[《類(4)》](https://github.com/qiwsir/StarterLearningPython/blob/master/209.md)中,介紹了一個函數super。為了描述方便,把代碼復制過來: ~~~ #!/usr/bin/env python # coding=utf-8 __metaclass__ = type class Person: def __init__(self): self.height = 160 def about(self, name): print "{} is about {}".format(name, self.height) class Girl(Person): def __init__(self): super(Girl, self).__init__() self.breast = 90 def about(self, name): print "{} is a hot girl, she is about {}, and her breast is {}".format(name, self.height, self.breast) super(Girl, self).about(name) if __name__ == "__main__": cang = Girl() cang.about("canglaoshi") ~~~ 在子類Girl中,因為重寫了父類的`__init__`方法,如果要調用父類該方法,在上節中不得不使用`super(Girl, self).__init__()`調用父類中因為子類方法重寫而被遮蔽的同名方法。 其實,在子類中,父類的方法就是**非綁定方法**,因為在子類中,沒有建立父類的實例,卻要是用父類的方法。對于這種非綁定方法的調用,還有一種方式。不過這種方式現在已經較少是用了,因為有了super函數。為了方便讀者看其它有關代碼,還是要簡要說明。 例如在上面代碼中,在類Girl中想調用父類Person的初始化函數,則需要在子類中,寫上這么一行: ~~~ Person.__init__(self) ~~~ 這不是通過實例調用的,而是通過類Person實現了對`__init__(self)`的調用。這就是調用非綁定方法的用途。但是,這種方法已經被super函數取代,所以,如果讀者在編程中遇到類似情況,推薦使用super函數。 ## [](https://github.com/qiwsir/StarterLearningPython/blob/master/210.md#靜態方法和類方法)靜態方法和類方法 已知,類的方法第一個參數必須是self,并且如果要調用類的方法,必須將通過類的實例,即方法綁定實例后才能由實例調用。如果不綁定,一般在繼承關系的類之間,可以用super函數等方法調用。 這里再介紹一種方法,這種方法的調用方式跟上述的都不同,這就是:靜態方法和類方法。看代碼: ~~~ #!/usr/bin/env python # coding=utf-8 __metaclass__ = type class StaticMethod: @staticmethod def foo(): print "This is static method foo()." class ClassMethod: @classmethod def bar(cls): print "This is class method bar()." print "bar() is part of class:", cls.__name__ if __name__ == "__main__": static_foo = StaticMethod() #實例化 static_foo.foo() #實例調用靜態方法 StaticMethod.foo() #通過類來調用靜態方法 print "********" class_bar = ClassMethod() class_bar.bar() ClassMethod.bar() ~~~ 對于這部分代碼,有一處非常特別,那就是包含了“@”符號。在python中: * `@staticmethod`表示下面的方法是靜態方法 * `@classmethod`表示下面的方法是類方法 一個一個來看。 先看靜態方法,雖然名為靜態方法,但也是方法,所以,依然用def語句來定義。需要注意的是文件名后面的括號內,沒有self,這和前面定義的類中的方法是不同的,也正是因著這個不同,才給它另外取了一個名字叫做靜態方法,否則不就“泯然眾人矣”。如果沒有self,那么也就無法訪問實例變量、類和實例的屬性了,因為它們都是借助self來傳遞數據的。 在看類方法,同樣也具有一般方法的特點,區別也在參數上。類方法的參數也沒有self,但是必須有cls這個參數。在類方法中,能夠方法類屬性,但是不能訪問實例屬性(讀者可以自行設計代碼檢驗之)。 簡要明確兩種方法。下面看調用方法。兩種方法都可以通過實例調用,即綁定實例。也可以通過類來調用,即`StaticMethod.foo()`這樣的形式,這也是區別一般方法的地方,一般方法必須用通過綁定實例調用。 上述代碼運行結果: ~~~ $ python 21001.py This is static method foo(). This is static method foo(). ******** This is class method bar(). bar() is part of class: ClassMethod This is class method bar(). bar() is part of class: ClassMethod ~~~ 這是關于靜態方法和類方法的簡要介紹。 正當我思考如何講解的更深入一點的時候,我想起了以往看過的一篇文章,覺得人家講的非常到位。所以,不敢吝嗇,更不敢班門弄斧,所以干醋把那篇文章恭恭敬敬的抄錄于此。同時,讀者從下面的文章中,也能對前面的知識復習一下。文章標題是:python中的staticmethod和classmethod的差異。原載:www.pythoncentral.io/difference-between-staticmethod-and-classmethod-in-python/。此地址需要你準備梯子才能瀏覽。后經國人翻譯,地址是:[http://www.wklken.me/posts/2013/12/22/difference-between-staticmethod-and-classmethod-in-python.html](http://www.wklken.me/posts/2013/12/22/difference-between-staticmethod-and-classmethod-in-python.html) 以下是翻譯文章: ### [](https://github.com/qiwsir/StarterLearningPython/blob/master/210.md#class-vs-static-methods-in-python)Class vs static methods in Python 這篇文章試圖解釋:什么事staticmethod/classmethod,并且這兩者之間的差異. staticmethod和classmethod均被作為裝飾器,用作定義一個函數為"staticmethod"還是"classmethod" 如果想要了解Python裝飾器的基礎,可以看[這篇文章](http://www.pythoncentral.io/python-decorators-overview/) ### [](https://github.com/qiwsir/StarterLearningPython/blob/master/210.md#simple-static-and-class-methods)Simple, static and class methods 類中最常用到的方法是 實例方法(instance methods), 即,實例對象作為第一個參數傳遞給函數 例如,下面是一個基本的實例方法 ~~~ class Kls(object): def __init__(self, data): self.data = data def printd(self): print(self.data) ik1 = Kls('arun') ik2 = Kls('seema') ik1.printd() ik2.printd() ~~~ 得到的輸出: ~~~ arun seema ~~~ 調用關系圖: [![](https://box.kancloud.cn/2015-09-07_55ed41ca9643f.png)](https://github.com/qiwsir/StarterLearningPython/blob/master/2images/21001.png) 查看代碼和圖解: > 1/2 參數傳遞給函數 > > 3 self參數指向實例本身 > > 4 我們不需要顯式提供實例,解釋器本身會處理 假如我們想僅實現類之間交互而不是通過實例?我們可以在類之外建立一個簡單的函數來實現這個功能,但是將會使代碼擴散到類之外,這個可能對未來代碼維護帶來問題。 例如: ~~~ def get_no_of_instances(cls_obj): return cls_obj.no_inst class Kls(object): no_inst = 0 def __init__(self): Kls.no_inst = Kls.no_inst + 1 ik1 = Kls() ik2 = Kls() print(get_no_of_instances(Kls)) ~~~ 結果: ~~~ 2 ~~~ ### [](https://github.com/qiwsir/StarterLearningPython/blob/master/210.md#the-python-classmethod)The Python @classmethod 現在我們要做的是在類里創建一個函數,這個函數參數是類對象而不是實例對象. 在上面那個實現中,如果要實現不獲取實例,需要修改如下: ~~~ def iget_no_of_instance(ins_obj): return ins_obj.__class__.no_inst class Kls(object): no_inst = 0 def __init__(self): Kls.no_inst = Kls.no_inst + 1 ik1 = Kls() ik2 = Kls() print iget_no_of_instance(ik1) ~~~ 結果 ~~~ 2 ~~~ 可以使用Python2.2引入的新特性,使用@classmethod在類代碼中創建一個函數 ~~~ class Kls(object): no_inst = 0 def __init__(self): Kls.no_inst = Kls.no_inst + 1 @classmethod def get_no_of_instance(cls_obj): return cls_obj.no_inst ik1 = Kls() ik2 = Kls() print ik1.get_no_of_instance() print Kls.get_no_of_instance() ~~~ We get the following output: ~~~ 2 2 ~~~ ### [](https://github.com/qiwsir/StarterLearningPython/blob/master/210.md#the-python-staticmethod)The Python @staticmethod 通常,有很多情況下一些函數與類相關,但不需要任何類或實例變量就可以實現一些功能. 比如設置環境變量,修改另一個類的屬性等等.這種情況下,我們也可以使用一個函數,一樣會將代碼擴散到類之外(難以維護) 下面是一個例子: ~~~ IND = 'ON' def checkind(): return (IND == 'ON') class Kls(object): def __init__(self,data): self.data = data def do_reset(self): if checkind(): print('Reset done for:', self.data) def set_db(self): if checkind(): self.db = 'new db connection' print('DB connection made for:',self.data) ik1 = Kls(12) ik1.do_reset() ik1.set_db() ~~~ 結果: ~~~ Reset done for: 12 DB connection made for: 12 ~~~ 現在我們使用@staticmethod, 我們可以將所有代碼放到類中 ~~~ IND = 'ON' class Kls(object): def __init__(self, data): self.data = data @staticmethod def checkind(): return (IND == 'ON') def do_reset(self): if self.checkind(): print('Reset done for:', self.data) def set_db(self): if self.checkind(): self.db = 'New db connection' print('DB connection made for: ', self.data) ik1 = Kls(12) ik1.do_reset() ik1.set_db() ~~~ 得到的結果: ~~~ Reset done for: 12 DB connection made for: 12 ~~~ ### [](https://github.com/qiwsir/StarterLearningPython/blob/master/210.md#how-staticmethod-and-classmethod-are-different)How @staticmethod and @classmethod are different ~~~ class Kls(object): def __init__(self, data): self.data = data def printd(self): print(self.data) @staticmethod def smethod(*arg): print('Static:', arg) @classmethod def cmethod(*arg): print('Class:', arg) ~~~ 調用 ~~~ >>> ik = Kls(23) >>> ik.printd() 23 >>> ik.smethod() Static: () >>> ik.cmethod() Class: (<class '__main__.Kls'>,) >>> Kls.printd() TypeError: unbound method printd() must be called with Kls instance as first argument (got nothing instead) >>> Kls.smethod() Static: () >>> Kls.cmethod() Class: (<class '__main__.Kls'>,) ~~~ 圖解 [![](https://box.kancloud.cn/2015-09-07_55ed41d2e8d6f.png)](https://github.com/qiwsir/StarterLearningPython/blob/master/2images/21002.png) ## [](https://github.com/qiwsir/StarterLearningPython/blob/master/210.md#文檔字符串)文檔字符串 在寫程序的時候,必須要寫必要的文字說明,沒別的原因,除非你的代碼寫的非常容易理解,特別是各種變量、函數和類等的命名任何人都能夠很容易理解,否則,文字說明是不可缺少的。 在函數、類或者文件開頭的部分寫文檔字符串說明,一般采用三重引號。這樣寫的最大好處是能夠用help()函數看。 ~~~ """This is python lesson""" def start_func(arg): """This is a function.""" pass class MyClass: """Thi is my class.""" def my_method(self,arg): """This is my method.""" pass ~~~ 這樣的文檔是必須的。 當然,在編程中,有不少地方要用“#”符號來做注釋。一般用這個來注釋局部。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看