中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

python類和對象的定義是什么

發布時間:2021-07-07 15:55:14 來源:億速云 閱讀:260 作者:chen 欄目:編程語言

這篇文章主要講解了“python類和對象的定義是什么”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“python類和對象的定義是什么”吧!

python 類和對象

1. 類的定義

class 類名([父類]):
  pass

# 當沒有父類要繼承時,()可以省略
class 類名:
  pass
  • 類也是一個對象,其類型是 <class 'type'>

  • 類名只是作為一個變量,定義類后,可以為類名賦值別的對象。

  • 使用類創建對象后,可以為任意對象隨意添加屬性

語法:對象.屬性名 = 屬性值   # 這個屬性在類中未定義
  • 在類中我們所定義的變量,將會成為所有的實例的公共屬性

2. 方法調用

1. 方法調用和函數調用的區別

如果是函數調用,則調用時傳幾個參數,就會有幾個實參

但是如果是方法調用,默認將調用該方法的對象傳遞給方法的第一個參數,所以方法中至少要定義一個形參,這個形參一般取名為self

class Person :
    # 在類的代碼塊中,我們可以定義變量和函數
    # 在類中我們所定義的變量,將會成為所有的實例的公共屬性
    # 所有實例都可以訪問這些變量
    name = 'ayy' # 公共屬性,所有實例都可以訪問

    # 在類中也可以定義函數,類中的定義的函數,我們稱為方法
    # 這些方法可以通過該類的所有實例來訪問
    
    def say_hello(self) :
        # 方法每次被調用時,解析器都會自動傳遞給方法的第一個實參
        # 第一個參數,就是調用方法的對象本身,
        # 一般我們都會將這個參數命名為self
        print('你好!我是 %s' %self.name)

# 創建Person的實例
p1 = Person()
p2 = Person()

3. 對象訪問屬性的查找流程

python中每個對象可以隨意添加自己的屬性,這一點和java不同,java同一類的實例擁有的成員變量是相同的。

- 類中定義的屬性和方法都是公共的,任何該類實例都可以訪問

    - 屬性和方法查找的流程
        當我們調用一個對象的屬性時,解析器會先在當前對象中尋找是否含有該屬性,
            如果有,則直接返回當前的對象的屬性值,
            如果沒有,則去當前對象的類對象中去尋找,如果有則返回類對象的屬性值,
            如果類對象中依然沒有,則報錯!

    - 類對象和實例對象中都可以保存屬性(方法)
        - 如果這個屬性(方法)是所有的實例共享的,則應該將其保存到類對象中
        - 如果這個屬性(方法)是某個實例獨有,則應該保存到實例對象中     
        
    - 一般情況下,屬性保存到實例對象中,而方法需要保存到類對象中
  • 類對象也可以存儲屬性并初始化,可以通過類名.屬性名直接訪問。

def Test():
    name = "ayy"
t = Test()
print(t.name)    # 因為實例t里面并沒有name屬性,所以去類對象里面去查找
t.name = "myt"   # 實例t并沒有name屬性,所以給實例t添加了一個name屬性,這里并不是修改了類對象的name屬性值
print(Test.name) # 類對象的屬性值沒有發生變化
  • python類中的方法和屬性類似于java中的靜態變量和方法,全部是公有的,所有實例均可以訪問到。但是方法不能直接訪問類的屬性,只能通過self參數來訪問。

    方法每次調用時都會自動傳入一個參數,即調用該方法的對象本身,一般命名成self。

3. 對象的創建流程

1.創建一個變量

2.在內存中創建一個新對象

3. 執行類中代碼塊中的方法,并且只在類定義的時候執行一次,類似于java類中的靜態代碼塊

4.__init__(self)方法執行(類似于構造方法),可以傳遞多個參數,用于為對象添加屬性值
  # __init__會在對象創建以后立即執行
  # __init__可以用來向新創建的對象中初始化屬性
  # 調用類創建對象時,類后邊的所有參數都會依次傳遞到__init__中

5.將對象的id賦值給變量
class Person()
    unit = "中汽研"     # 為類添加屬性
    print("hello")     # 類中的代碼只在類定義時執行一次
	def __init__(self,name)
    	self.name = name    # 為每個對象添加屬性
 
p = Person("ayy")      # 構造器傳參

4. 封裝

1. 通過setter和getter

# 封裝是面向對象的三大特性之一
# 封裝指的是隱藏對象中一些不希望被外部所訪問到的屬性或方法
# 如何隱藏一個對象中的屬性?
#   - 將對象的屬性名,修改為一個外部不知道的名字
# 如何獲取(修改)對象中的屬性?
#   - 需要提供一個getter和setter方法使外部可以訪問到屬性
#   - getter 獲取對象中的指定屬性(get_屬性名)
#   - setter 用來設置對象的指定屬性(set_屬性名)
# 使用封裝,確實增加了類的定義的復雜程度,但是它也確保了數據的安全性
#   1.隱藏了屬性名,使調用者無法隨意的修改對象中的屬性
#   2.增加了getter和setter方法,很好的控制的屬性是否是只讀的
#       如果希望屬性是只讀的,則可以直接去掉setter方法
#       如果希望屬性不能被外部訪問,則可以直接去掉getter方法
#   3.使用setter方法設置屬性,可以增加數據的驗證,確保數據的值是正確的
#   4.使用getter方法獲取屬性,使用setter方法設置屬性
#       可以在讀取屬性和修改屬性的同時做一些其他的處理
#   5.使用getter方法可以表示一些計算的屬性

class Dog:
    '''
        表示狗的類
    '''
    def __init__(self , name , age):
        self.hidden_name = name
        self.hidden_age = age

    def say_hello(self):
        print('大家好,我是 %s'%self.hidden_name) 

    def get_name(self):
        '''
            get_name()用來獲取對象的name屬性
        '''    
        # print('用戶讀取了屬性')
        return self.hidden_name

    def set_name(self , name):
        # print('用戶修改了屬性')
        self.hidden_name = name

    def get_age(self):
        return self.hidden_age

    def set_age(self , age):
        if age > 0 :
            self.hidden_age = age    

d = Dog('旺財',8)

# 調用setter來修改name屬性 
d.set_name('小黑')
d.set_age(-10)
print(d.get_age())

2. 私有屬性

可以為對象的屬性使用雙下劃線開頭,__xxx
雙下劃線開頭的屬性,是對象的隱藏屬性,隱藏屬性只能在類的內部訪問,無法通過對象訪問
其實隱藏屬性只不過是Python自動為屬性改了一個名字,實際上是將名字修改為了 _類名__屬性名

通過 _類名__屬性名仍然可以訪問到對象的成員變量并對其進行修改,無法做到完全隱藏,但是無法通過原有的名字訪問。

一般不通過私有屬性來實現封裝

3. @property

對象調用setter,gettter時候,

class Person:
  
    # property裝飾器,用來將一個get方法,轉換為對象的屬性
    # 添加為property裝飾器以后,我們就可以像調用屬性一樣使用get方法
    # 使用property裝飾的方法,必須和屬性名是一樣的
    @property    
    def name(self):
        print('get方法執行了~~~')
        return self._name

    # setter方法的裝飾器:@屬性名.setter
    @name.setter    
    def name(self , name):
        print('setter方法調用了')
        self._name = name        

    @property
    def age(self):
        return self._age

    @age.setter    
    def age(self , age):
        self._age = age     

p = Person()

p.name = '孫悟空'
p.age = 28

print(p.name,p.age)
  • @property修飾在get方法上面,將和屬性同名的方法轉換成對應的getter

  • @屬性名.setter修飾在setter上面,將和屬性同名的方法轉換成對應的setter

  • 注意:只有定義好getter之后才能定義setter

5. 繼承

子類會繼承父類所有的方法和屬性,包括特殊方法,例如初始化方法

1. 在創建類時,如果省略了父類,則默認父類為object。object是所有類的父類,所有類都繼承自object

class Person(object):
    pass
  • issubclass() 檢查一個類是否是另一個類的子類

    print(issubclass(Animal , Dog))


  • isinstance()用來檢查一個對象是否是一個類的實例

    如果這個類是這個對象的父類,也會返回True,所有的對象都是object的實例

    print(isinstance(print , object))


2. 方法重寫

如果在子類中如果有和父類同名的方法,則通過子類實例去調用方法時,會調用子類的方法而不是父類的方法,這個特點我們成為叫做方法的重寫(覆蓋,override)

當我們調用一個對象的方法時,會優先去當前對象中尋找是否具有該方法,如果有則直接調用,如果沒有,則去當前對象的父類中尋找,如果父類中有則直接調用父類中的方法,如果沒有,則去父類的父類中尋找,以此類推,直到找到object,如果依然沒有找到,則報錯。

3. 多繼承

-前邊父類的方法會覆蓋后邊父類的方法

class A(object):
    def test(self):
        print('AAA')

class B(object):
    def test(self):
        print('B中的test()方法~~')

""" 在Python中是支持多重繼承的,也就是我們可以為一個類同時指定多個父類,可以在類名的()后邊添加多個類,來實現多重繼承
   多重繼承,會使子類同時擁有多個父類,并且會獲取到所有父類中的方法
   在開發中沒有特殊的情況,應該盡量避免使用多重繼承,因為多重繼承會讓我們的代碼過于復雜
   如果多個父類中有同名的方法,則會現在第一個父類中尋找,找不到然后找第二個,然后找第三個。。。
   前邊父類的方法會覆蓋后邊父類的方法
"""
class C(A,B):
    pass

# 類名.__bases__ 這個屬性可以用來獲取當前類的所有父類    

print(B.__bases__)  # (<class 'object'>,)
print(C.__bases__)  # (<class '__main__.A'>, <class '__main__.B'>)

c = C()
c.test()

4. 調用父類初始化方法與繼承

class Animal:
    def __init__(self,name):
        self._name = name

    def run(self):
        print('動物會跑~~~')

    def sleep(self):
        print('動物睡覺~~~')

    @property
    def name(self):
        return self._name

    @name.setter    
    def name(self,name):
        self._name = name

# 父類中的所有方法都會被子類繼承,包括特殊方法,也可以重寫特殊方法
class Dog(Animal):

    def __init__(self,name,age):
        # 希望可以直接調用父類的__init__來初始化父類中定義的屬性
        # super() 可以用來獲取當前類的父類,
        #   并且通過super()返回對象調用父類方法時,不需要傳遞self
        super().__init__(name)
        self._age = age

    def bark(self):
        print('汪汪汪~~~') 

    def run(self):
        print('狗跑~~~~')   

    @property
    def age(self):
        return self._age

    @age.setter    
    def age(self,age):
        self._age = name        

d = Dog('旺財',18) 

print(d.name)       
print(d.age)
  1. 子類可以定義自己的 __ init __方法,這樣就會把父類的給覆蓋掉。(python語法不支持重載),如何在子類的初始化方法中調用父類的初始化方法?

1. super().__init__(屬性.....)  # 不需要傳入self
  super() 返回當前類的父類,調用初始化方法不需要傳遞self
    
2.父類.__init__(self,屬性.....)
  調用成員方法,需要傳入一個當前對象。
  1. 父類,子類的 __ init __與屬性繼承

1. 如果子類繼承父類不做初始化(這里指的是子類中沒有__ init __初始化函數),那么這時子類會自動繼承父類屬性。

2、如果子類繼承父類做了初始化(這里指的是子類中有__ init __函數,對子類特有的屬性進行了初始化),且不調用super初始化父類構造函數,那么子類不會自動繼承父類的屬性。

3、如果子類繼承父類做了初始化,且調用了super初始化了父類的構造函數,那么子類也會繼承父類的屬性。注意:子類初始化函數中要將父類的 __ init __函數中的父類屬性全部包含進來;

原因很簡單,對象的屬性是在初始化方法里面添加的,如果子類不調用init方法,那么自然不會添加父類對應的對象的屬性。

6. 類中的屬性和方法

  • 通過類調用實例方法時,不會自動傳遞self,此時我們必須手動傳遞self對象到方法中。

"""
   類屬性
   實例屬性
   類方法
   實例方法
   靜態方法

"""
class A(object):
    #   類屬性,直接在類中定義的屬性是類屬性
    #   類屬性可以通過類或類的實例訪問到
    #   但是類屬性只能通過類對象來修改,無法通過實例對象修改
    count = 0
    def __init__(self):
        # 實例屬性,通過實例對象添加的屬性屬于實例屬性
        #   實例屬性只能通過實例對象來訪問和修改,類對象無法訪問修改
        self.name = '孫悟空'

    # 實例方法
    #   在類中定義,以self為第一個參數的方法都是實例方法
    #   實例方法在調用時,Python會將調用對象作為self傳入  
    #   實例方法可以通過實例和類去調用
    #       當通過實例調用時,會自動將當前調用對象作為self傳入
    #       當通過類調用時,不會自動傳遞self,此時我們必須手動傳遞self,注意這個self就是對象對應的引用變量
    def test(self):
        print('這是test方法~~~ ' , self)    

    # 類方法    
    # 在類內部使用 @classmethod 來修飾的方法屬于類方法
    # 類方法的第一個參數是cls,也會被自動傳遞,cls就是當前的類對象
    #   類方法和實例方法的區別,實例方法的第一個參數是self,而類方法的第一個參數是cls
    #   類方法可以通過類去調用,也可以通過實例調用,沒有區別
    @classmethod
    def test_2(cls):
        print('這是test_2方法,他是一個類方法~~~ ',cls)
        print(cls.count)

    # 靜態方法
    # 在類中使用 @staticmethod 來修飾的方法屬于靜態方法  
    # 靜態方法不需要指定任何的默認參數,靜態方法可以通過類和實例去調用  
    # 靜態方法,基本上是一個和當前類無關的方法,它只是一個保存到當前類中的函數
    # 靜態方法一般都是一些工具方法,和當前類無關
    @staticmethod
    def test_3():
        print('test_3執行了~~~')

a = A()

感謝各位的閱讀,以上就是“python類和對象的定義是什么”的內容了,經過本文的學習后,相信大家對python類和對象的定義是什么這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

桐庐县| 调兵山市| 西贡区| 钦州市| 桑日县| 江安县| 伽师县| 吐鲁番市| 伊金霍洛旗| 饶阳县| 临汾市| 犍为县| 安庆市| 龙里县| 阿拉尔市| 余庆县| 邯郸市| 沐川县| 定兴县| 新巴尔虎左旗| 定州市| 宁城县| 霍州市| 桦南县| 望奎县| 邢台县| 芷江| 美姑县| 惠水县| 呈贡县| 兴山县| 阿城市| 华池县| 云阳县| 张家港市| 固阳县| 岳阳县| 锦州市| 江油市| 固安县| 连平县|