2012-09-23 18 views
1
  1. 這兩個類聲明有什麼區別? 「對象」是做什麼的?Python新手:頭疼面向對象編程

    class className(object): 
        pass 
    
    class className: 
        pass 
    
  2. 當我運行下面的代碼爲什麼我得到這個錯誤: 「時不採取任何(給出1)參數」

    class Hobbs(): 
        def represent(): 
         print "Hobbs represent!" 
        represent = classmethod(represent) 
    
    Hobbs.represent() 
    
  3. 爲什麼 「Foo.class_foo()」 給沒有錯誤即使我沒有傳遞函數的參數。

    class Foo(object): 
        @staticmethod 
        def static_foo(): 
        print "static method" 
        @classmethod 
        def class_foo(cls): 
         print "Class method. Automatically passed the class: %s" % cls  
    Foo.static_foo() 
    Foo.class_foo() 
    
  4. 爲什麼我運行下面的代碼時會出現此錯誤?

    class Foo(object): 
        def static_foo(): 
         print "static method" 
         static_foo = staticmethod(static_foo) 
        def class_foo(cls): 
          print "Class method. Automatically passed the class: %s" % cls 
        class_foo = classmethod(class_foo) 
    Foo.static_foo() 
    Foo.class_foo() 
    

"TypeError: unbound method static_foo() must be called with Foo instance as first argument (got nothing instead)"

+0

您應該閱讀[Python教程](http://docs.python.org/tutorial/)以熟悉Python中的這些基類。 – BrenBarn

回答

0

所有類函數必須採取自我作爲第一個參數

class A: 
    def my_func(self): 
     print "In my func" 

靜態方法是非常簡單,只是在命名空間中的功能(和很少使用的類python)

類方法是應該在類本身上調用的類名稱空間中的函數r因爲至少在Python 2.2粥不是一個實例

5
  1. 使用object作爲新類的基類已經約定,被稱爲「新樣式類」 - 見this question瞭解更多詳情。舊式的類(即:不從object繼承的類)在Python 3.0中被設置爲不推薦使用。這些變化的原因有些模糊,並且與低層次的類解析和繼承模式有關。

  2. 按照慣例,Python實例方法以self作爲它們的第一個參數。這個參數是隱式傳遞的 - 所以如果你的方法定義不需要self,那麼解釋器會抱怨你試圖調用的方法不接受自動傳遞給它的參數。這與classmethods的工作方式完全相同,只是不採取self,他們通常採用cls。 (只是一個命名約定。)速戰速決:

    class Hobbs(): 
        def represent(cls): 
         print "Hobbs represent!" 
        represent = classmethod(represent) 
    
    Hobbs.represent() 
    
  3. 調用Foo.class_foo()不會引起任何問題,因爲Python中會自動將類對象的class_foo方法,每當你怎麼稱呼它。這些方法被稱爲綁定方法 - 意味着它們是常規函數,但綁定到類或實例對象。綁定方法自動將它們綁定的類或實例對象作爲它們的第一個參數。

  4. 縮進級別在Python中很重要。我試着執行你提供的代碼示例,但是static_foo =class_foo =這兩行必須在Foo類定義中,而不是在其下面或其他方法中。當正確縮進,代碼精運行:

    class Foo(object): 
        def static_foo(): 
         print "static method" 
        static_foo = staticmethod(static_foo) 
        def class_foo(cls): 
         print "Class method. Automatically passed the class: %s" % cls 
        class_foo = classmethod(class_foo) 
    Foo.static_foo() 
    Foo.class_foo() 
    
+0

謝謝,我現在得到了所有要點。 – user1586038

0

你的大多數問題是不是真正的面向對象本身,而是Python的具體執行它。

  1. Python 2.x已經發生了一些變化,並添加了新功能。所以有兩種方法來定義類,產生「新式類」和「舊式類」。 Python 3.x只有「新風格類」。 新風格類的基礎對象被稱爲object。如果你繼承了你有一個新風格的類。它給你一些額外的功能,如某些裝飾器。如果你在Python 2.x中有一個純粹的(沒有繼承)定義,那麼你有一箇舊式的類。這是爲了向後兼容。在Python 3.x中,您還將獲得一個新式類(因此從object繼承是可選的)。

  2. 您已製作represent()和「class method」。所以它會在被調用時將類對象作爲隱含的第一個參數。但那些只適用於新式課程。你曾嘗試將它與舊式課堂一起使用。所以它不會工作。

  3. Python自動將類對象作爲參數零插入類方法。所以這是正確的模式,它的工作原理。

  4. 該方法某種程度上沒有得到make類方法,也許是因爲縮進是錯誤的。

0
  1. class ClassName(OtherClass):意味着從類名 OtherClass繼承。繼承是一個很大的主題,但基本上這意味着 ClassName與OtherClass至少具有相同的功能和字段。

    在Python中,一切都是一個對象,因此,所有類都從對象隱式或明確地繼承 。這就是說

    class ClassName():聲明是一個古老的語法,應該避免。

    class ClassName:相當於類ClassName(object):

  2. 類方法不是靜態方法。它就像任何其他實例方法,除了它作爲參數傳遞類而不是實例。

    您的類方法聲明是錯誤的。它應該有一個CLS參數。

  3. 另一方面,靜態方法是一種被稱爲超出上下文的方法。這意味着它與任何實例都沒有關係。它可以被認爲是一個獨立的功能,只是爲了語義的原因放在一個類中。

    這就是爲什麼它不需要自我參數,並且一個永遠不會傳遞給它。

  4. 您有一個縮進錯誤。這可能會導致錯誤。

+0

'class ClassName:'在Python 2中與* class ClassName(object):*不同*前者創建一箇舊式類。它*與* class ClassName()相同:(在所有版本中)。 – lvc

1
  1. 最後兩個是相同的 - 空方括號是相同的省略它們。第一個繼承自內建類object,使其成爲「新風格類」。新舊風格類的原因是歷史的,舊風格只是爲了向後兼容而保留 - 本質上,在Python 2中,如果你不從其他任何東西繼承,建議總是繼承自object,因爲你會學到的花哨技巧最終依靠它。如果升級到Python 3,這將成爲默認行爲,並且所有三個類聲明都是等效的。

  2. 一個classmethod需要採取類似self第一個參數 - 當你打電話Hobbs.represent(),巨蟒最後傳遞Hobbs在作爲第一個參數。這是classmethodstaticmethod之間的基本區別 - 一個classmethod接受第一個參數(即被調用的類),staticmethod不接受。

  3. 與2級相同通過classmethod代替通常的self

  4. 這一次似乎是一個壓痕問題 - 你的代碼的工作,如果它是縮進的書面:

    def static_foo(): 
        print "static method" 
    static_foo = staticmethod(staticfoo) 
    

但不能作爲

def static_foo(): 
    print "static method" 
    static_foo = staticmethod(staticfoo)  

因爲線路重新分配static_foo需要在課堂上,而不是功能本身的一部分。在後者中,該行在函數運行之前不會執行(這意味着它不會運行,因爲函數錯誤) - 並且它將一個局部變量而不是該方法本身分配給一個局部變量。這種類型的錯誤是使用裝飾器語法很好的原因之一:

class Hobbs: 
    @staticmethod 
    def static_foo(): 
     print "static method" 

的作品。