python 3 基礎之 類和實例 的 屬性和方法(類的屬性和方法的重寫、調用、私有、修改)


 

1、類的屬性和方法的重寫、調用、私有、修改

  1.1、重寫:子類重寫父類同名屬性和方法

    如果兩個子類和父類的方法名和屬性相同,默認使用子類的,子類雖然方法名和屬性與父類相同,但是進行了修改,使用子類的方法和屬性做子類獨有的事情,這就叫做子類重寫父類同名屬性和方法

# 定義三個類,一個子類繼承兩個父類
class R(object):
    # 類的屬性
    def __init__(self): self.name = '父類R' # 類的方法 def Xinxi(self): print('學生的基本資料:名字:%s' % self.name) class X(object): def __init__(self): self.name = '父類X' def Xinxi(self): print('學生的基本資料:名字:%s' % self.name) class G(R,X): def __init__(self): self.name = '子類獨有' def Xinxi(self): print('只需要名字:%s' % self.name) xiaoming = G() # 子類和父類有同名的屬性 xiaoming.Xinxi()# 子類和父類有同名的方法,但子類做自己獨有的事情

  1.2、子類調用父類同名的屬性和方法

    在子類中新建一個子類的方法,方法內容調用父類的方法,然后子類調用對應的方法,如此間接達到子類調用父類方法的目的

# 定義三個類,一個子類繼承兩個父類
class R(object):
    # 類的方法
    def Xinxi(self): print('學生的基本資料:名字:R') class X(object): def Xinxi(self): print('學生的基本資料:名字:X') class G(R,X): def Xinxi(self): print('只需要名字:G') def Xxinxi(self): X.Xinxi(self) def Rxinxi(self): R.Xinxi(self) # 實例化對象,自動執行子類的__init__方法 xiaoming = G() # 調用本類的實例方法: 子類和父類同名的方法,但子類做自己獨有的事情 xiaoming.Xinxi() # 進入實例方法去調用父類X、R的方法 xiaoming.Xxinxi() xiaoming.Rxinxi()

  當然,不同名的父類方法,子類繼承后可以直接調用

  1.3、通過super()來調用父類方法

    super()通過子類調用當前父類的方法,super默認會調用第一個父類的方法(適用於單繼承的多層繼承 或者只想使用第一個父類的方法)

class R(object):
    # 類的方法
    def Xinxi(self): print('學生的基本資料:名字:R') class X(object): def Xinxi(self): print('學生的基本資料:名字:X') class G(X,R): def Xinxi(self): # 調用父類的方法 print('只需要名字:G') R.Xinxi(self) X.Xinxi(self) def all_Xinxi(self): super().Xinxi() wan = G() # 調用父類方法 wan.all_Xinxi()

  1.4、私有屬性和私有方法

     Python是以屬性命名方式來區分,如果在屬性和方法名前面加了2個下划線'__',則表明該屬性和方法是私有權限,否則為公有權限

    類的私有屬性和 私有方法,都不能通過對象直接訪問,但是可以在本類內部訪問;

    類的私有屬性 和 私有方法,都不會被子類繼承,子類也無法訪問

    私有屬性 和 私有方法 往往用來處理類的內部事情,不通過對象處理,起到安全作用。

  私有屬性和方法示例:

class Master(object):
    # 構造方法
    def __init__(self): self.kongfu = '古法配方' # 添加一個屬性 # 如果一個屬性的名字開頭是兩個下划線,代表此屬性是私有的 self.__money = 1000 # 制作煎餅果 def make_cake(self): print('古法煎餅果') print(self.__money)#私有屬性只能在類的里面使用 self.__print()#私有方法可以在類的內部使用 # 定義一個私有方法 def __print(self): print('這是私有方法') lishifu = Master() print(lishifu.kongfu) # 若一個屬性私有后,就不能使用對象調用此屬性(私有屬性不能在類的外面使用) # print(lishifu.__money) lishifu.make_cake() # lishifu.__print()#這是私有方法,不能調用 class Prentice(Master): pass damao = Prentice() print(damao.kongfu) damao.make_cake() # 結論:子類繼承父類,若父類屬性或方法私有后,將不會被繼承,只能在父類里使用

  1.5、修改私有屬性的值

  修改私有屬性的值一般有兩種方法:

    直接修改:對象名 . 屬性名 = 新數據

    通過兩個方法間接修改:對象名 . 方法名(新數據)

  如下代碼,屬於間接修改屬性的值

# 自定義一個人類
class person(object):
    def __init__(self): self.name = '小明' self.__age = 20#私有屬性 # 定義一個方法(獲取屬性的值,一般方法中使用get) def get_age(self):#用於返回一個私有屬性的值 return self.__age # 定義一個方法,對屬性賦值的時候一般方法中使用set def set_age(self,new_age): self.__age = new_age xiao = person() print(xiao.get_age())#使用對象調用私有屬性完成打印age的值 xiao.set_age(33)#使用對象設置屬性的值 print(xiao.get_age())

 2、類屬性和實例屬性

  顧名思義,類屬性就是類對象所擁有的屬性,它被所有類對象實例對象所共有,在內存中只存在一個副本,對於公有的類屬性,在類外可以通過類對象實例對象訪問

  2.1、類屬性

    類屬性的好處:每定義個對象實例屬性會占用一份內存,而類屬性只占用一份內存,使用類屬性可以節約空間提高性能,為后期業務需求更改,方便開發

    訪問:不能在類外通過實例對象訪問私有類屬性,可以訪問共有的類屬性

class People(object):
    name = 'Tom'  # 公有的類屬性
    __age = 12  # 私有的類屬性
 p = People() print(p.name) # 正確 print(People.name) # 正確 print(p.__age) # 錯誤,不能在類外通過實例對象訪問私有的類屬性 print(People.__age) # 錯誤,不能在類外通過類對象訪問私有的類屬性

  2.2、實例屬性

class People(object):
    address = '山東'  # 類屬性
    def __init__(self): self.name = 'xiaowang' # 實例屬性 self.age = 20 # 實例屬性  p = People() p.age = 12 # 實例屬性 print(p.address) # 正確 print(p.name) # 正確 print(p.age) # 正確 print(People.address) # 正確 print(People.name) # 錯誤 print(People.age) # 錯誤

  2.3、通過實例去修改類屬性

class People(object):
    country = 'china' #類屬性

print(People.country) p = People() print(p.country) p.country = 'japan' print(p.country) # 實例屬性會屏蔽掉同名的類屬性 print(People.country) del p.country # 刪除實例屬性 print(p.country)

運行結果:

china
china
japan
china
china

  如果需要在類外修改類屬性,必須通過類對象去引用然后進行修改。如果通過實例對象去引用,會產生一個同名的實例屬性,這種方式修改的是實例屬性,不會影響到類屬性,並且之后如果通過實例對象去引用該名稱的屬性,實例屬性會強制屏蔽掉類屬性,即引用的是實例屬性,除非刪除了該實例屬性

  2.4、實例屬性和方法的開辟空間規則

    創建對象占用內存地址,對象的屬性也另外占用內存地址,對象占用的地址與對象屬性占用的地址不一樣(同一個類創建的對象,其屬性的占用地址不一樣)

    不同的對象,但是調用的對象、方法的id相同(地址相同),因為調用的是同一個方法

    創建不同對象表達的是不同的人,其屬性特征是不同的,但方法相同,因為方法中有個形參self可以區分是哪個對象調用的

class Person(object):
    def __init__(self,name):
        self.name = name
    def eat(self):
        print('人會吃飯')
# 使用一個類創建一個對象后,就會占用內存地址(空間)
# 用id查看空間地址,如print(id(xiaoming))
# 對象的內存地址不同,代表各占一個空間
xiaoming = Person('小明')
print(id(xiaoming))
print(id(xiaoming.name))
print(id(xiaoming.eat()))

xiaohong = Person('小紅')
xiaohong.eat()
print(id(xiaohong.name))
print(id(xiaohong))#創建兩個對象后需要分別開辟空間,占用內存較多
print(id(xiaohong.eat()))

  2.5、類方法和靜態方法

    2.5.1、類方法

  類方法是類對象所擁有的方法,需要用修飾器@classmethod來標識其為類方法

  對於類方法,第一個參數必須是類對象,一般以cls作為第一個參數(當然可以用其他名稱的變量作為其第一個參數,但是大部分人都習慣以'cls'作為第一個參數的名字,就最好用'cls'了),能夠通過實例對象和類對象去訪問。

  實例方法的第一個參數是實例對象self,那么通過self引用的可能是類屬性、也有可能是實例屬性(這個需要具體分析),不過在存在相同名稱的類屬性和實例屬性的情況下,實例屬性優先級更高。

  靜態方法中不需要額外定義參數,因此在靜態方法中引用類屬性的話,必須通過類實例對象來引用

class People(object):
    country = 'china'

    #類方法,用classmethod來進行修飾
    @classmethod
    def get_country(cls):
        return cls.country

p = People()
print(p.get_country())    #可以用過實例對象引用
print(People.get_country())    #可以通過類對象引用

    2.5.2、類方法對類屬性進行修改

class People(object):
    country = 'china'

    #類方法,用classmethod來進行修飾
    @classmethod
    def get_country(cls):
        return cls.country

    @classmethod
    def set_country(cls,country):
        cls.country = country

p = People()
print(p.get_country())   #可以用過實例對象訪問
print(People.get_country())    #可以通過類訪問

p.set_country('japan')   

print(p.get_country())
print(People.get_country())

  結果顯示在用類方法對類屬性修改之后,通過類對象和實例對象訪問都發生了改變

    2.5.3、靜態方法(了解)

      需要通過修飾器@staticmethod來進行修飾,靜態方法不需要多定義參數,可以通過對象和類來訪問。

class People(object):
    country = 'china'

    @staticmethod
    #靜態方法
    def get_country():
        return People.country

p = People()
# 通過對象訪問靜態方法
p.get_contry()

# 通過類訪問靜態方法
print(People.get_country())

 


免責聲明!

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



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