Python面向?qū)ο?類的理解

類(Class)是對某種類型的對象定義變量和方法的原型。它表示對現(xiàn)實(shí)生活中一類具有共同特征的事物的抽象,是面向?qū)ο缶幊痰幕A(chǔ)。

python中,私有的屬性或方法都必須前面加__(雙下劃線)

首先讓我們看一下Python中類的定義:

class People:
    galaxy = 'Galactic' #類屬性(公有屬性)
    __star = 'Earth'    #類屬性(私有屬性)
    
    def __init__(self, name, age): 
        self.__name = name  #(實(shí)例屬性:私有屬性)
        self.age = age  #(實(shí)例屬性:公有屬性)
    
    #類方法
    @classmethod
    def say(cls, mess):
        print "I say %s" % mess
    
    #實(shí)例方法
    def code(self, language):
        print "I can code use %s" % language
        
    #靜態(tài)方法    
    @staticmethod
    def run(velocity):
        print "I run %f km/h" % velocity
        

Python中的init(self, ...)在生成對象時調(diào)用(稱內(nèi)置方法),self參數(shù)相當(dāng)于Java中的this(可以寫成其他的參數(shù)名,不過一般都寫成self,便于理解),不需要顯示調(diào)用(即可以不用寫),系統(tǒng)默認(rèn)執(zhí)行,且支持重載,跟Java中的構(gòu)造函數(shù)類似,其它內(nèi)置方法還有del(self), __cmp__(), __len__()等等

以上類中出現(xiàn)的概念,下面都會詳細(xì)的介紹到

python中區(qū)分類屬性和實(shí)例屬性

類屬性

類屬性就是類本身(類也是一個對象,所有也可以叫類對象)所擁有的屬性,可以被該類的所有實(shí)例化對象所共有,在內(nèi)存中只有一個副本,和Java中的靜態(tài)成員變量相似。對于公有的類屬性,在類外面,既可以通過==類對象本身.屬性==訪問,也可以通過==實(shí)例對象.屬性==進(jìn)行訪問。

class People:
    name = 'nanxue'

p = People()    #實(shí)例化時,并不需要new
print p.name    # nanxue
print People.name     # nanxue

注意:雖然類定義的時候,類名后緊跟了冒號(class People:),但實(shí)例化時,必須寫成 instance = className() 的形式,如果類中有構(gòu)造函數(shù)的重載,則必須寫成重載的形式,比如這樣

class People:
    name = 'nanxue'
    
    def __init__(self,age):
        self.age = age
        
p = People(20)    #實(shí)例化時,并不需要new
p = People()      #error (TypeError: __init__() takes exactly 2 arguments (1 given))

實(shí)際上Python2.2以后,規(guī)定所有類都繼承自object基類,所以其實(shí)也可以這么寫 class People(object):

而私有的類屬性不管是類對象還是實(shí)例對象,在類外面都不能訪問,例如下面的訪問形式就會出錯

class People:
    __name = 'nanxue'

p = People()
print p.__name    # error(AttributeError: class People has no attribute '__name')
print People.__name     # error(AttributeError: People instance has no attribute '__name')

實(shí)例屬性

而實(shí)例屬性,只能通過實(shí)例對象訪問(類對象訪問不到,見第一種),實(shí)例屬性既可以在初始化的過程定義(init函數(shù)中通過self.屬性),也可以在實(shí)例化后動態(tài)的添加(此時,該屬性為這個實(shí)例所特有)

  • 第一種
class People:
    name = 'nanxue'

    def __init__(self,age):
        self.age = age

p = People(12)
print p.name    # nanxue
print p.age     # 12

print People.age  #error(AttributeError: class People has no attribute 'age')

  • 第二種
class People:
    name = 'nanxue'
    
p = People()
p.age = 12

print p.name    # nanxue
print p.age     # 12

pp = People()
print pp.age    #error(AttributeError: People instance has no attribute 'age')

與類屬性相同,在初始化函數(shù)中定義的私有實(shí)例屬性在類外面是訪問不到的,但是通過動態(tài)添加的私有屬性可以訪問的到

class People:
    name = 'nanxue'
   
    def __init__(self,age):
        self.__age = age
    
p = People(20)
print p.name    # nanxue
print p.__age   # error(AttributeError: People instance has no attribute '__age')

p.__sex = 2
print p.__sex   # 2

此時,還存在一種情況,就是在類中定義了一個類屬性,實(shí)例化后也動態(tài)添加一個同名屬性,會怎么樣呢?,會覆蓋嗎?

class People:
    name = 'nanxue'
   
    def __init__(self,age):
        self.age = age
    
p = People(20)
print p.name    # nanxue
print p.age     # 20

#同名屬性
p.age = 50
print p.age     # 50

p.name = 'aaa'
print p.name       # aaa
print People.name  # nanxue

del p.name
print p.name    # nanxue

可以看到,實(shí)例對象會產(chǎn)生一個同名的實(shí)例屬性,強(qiáng)制屏蔽掉類屬性,類屬性還是原來的值,如果刪除掉實(shí)例屬性,則恢復(fù)為類屬性,因此要修改類屬性的值,需通過類對象修改

class People:
    name = 'nanxue'
    
p = People()
print p.name    # nanxue

#同名屬性
p.name = 'aaa'
print p.name     # aaa

#新的實(shí)例對象
pp = People()
print pp.name    # nanxue

#修改類屬性
People.name = 'bbb'

print p.name     # aaa
print pp.name    # bbb

方法的區(qū)別

實(shí)例方法

顧名思義,為該類的實(shí)例所有,不能通過類對象引用實(shí)例方法,至少有一個參數(shù)且必須為實(shí)例對象,也必須作為該方法的第一個參數(shù)

class People:
    name = 'nanxue'
    
    #實(shí)例方法
    def code(self):
        return self.name
        
p = People()

print p.code()      # nanxue
print Peopel.code() # error(unbound method code() must be called with People instance as first argument (got nothing instead))

當(dāng)同時存在同名的類屬性與實(shí)例屬性時,實(shí)例屬性優(yōu)先級更高

類方法

方法前需加修飾符@classmethod,實(shí)例對象與類對象都可以引用,第一個參數(shù)必須是類對象,一般寫作cls

class People:
    name = 'nanxue'
    
    #類方法
    @classmethod
    def eat(cls):
        return cls.name
        
p = People()

print p.eat()      # nanxue
print People.eat() # nanxue

類方法可對類屬性進(jìn)行修改

class People:
    name = 'nanxue'
    
    #類方法
    @classmethod
    def setName(cls, name):
        cls.name = name
        
    @classmethod    
    def getName(cls):
return cls.name
        
p = People()

print p.getName()        # nanxue
print People.getName()   # nanxue

p.setName('xiaonan')
#People.setName('xiaonan')

print p.getName()        #xiaonan
print People.getName()   #xiaonan

靜態(tài)方法

靜態(tài)方法前需要加修飾符@staticmethod,不需要額外定義參數(shù)

class People:
    name = 'nanxue'
    
    #靜態(tài)方法
    @staticmethod
    def getStaticName():
        return People.name
        
p = People()

print p.getSaticName()        # error(People instance has no attribute 'getSaticName')
print People.getSaticName()   # nanxue

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容