Python : Class

来源:https://www.cnblogs.com/f1194361820/archive/2018/03/25/8645913.html
-Advertisement-
Play Games

Python 和 JavaScript一樣即是面向過程語言,也是面向對象語言,動態語言。大多數面向對象語言里,Class是必不可少的。面向對象有三大特性:封裝, 繼承,多態。在Python中Class到底是怎樣的呢? 1、Class組成 2、Class getter, setter 3、Class繼 ...


  Python 和 JavaScript一樣即是面向過程語言,也是面向對象語言,動態語言。大多數面向對象語言里,Class是必不可少的。面向對象有三大特性:封裝, 繼承,多態。在Python中Class到底是怎樣的呢?

1、Class組成

  先來看一個示例:

class Person(object):
    id=''
    name = ''
    age = 3
    
    # 等同於Java中的<init>,即構造器
    def __init__(self, id, name, age):
        print("init a Person instance")
        self.id = id
        self.name = name
        self.age = age

    def show(this):
        print(this)
    #   print(this.toString())

    #def toString(self):        
    #    return "id:{}, name:{}, age:{}".format(self.id, self.name, self.age)
    
    # 等同於Java中的toString
    def __str__(self):
    #   return self.toString()
        return "id:{}, name:{}, age:{}".format(self.id, self.name, self.age)
    

    # 等同於Java中的finalize方法,del 實例時調用
    def __del__(self):
        print("finally a Person instance")
        self.id = None
        self.name = None
        self.age = None
        self = None
    

 


  下麵是以對比Java的方式,來說明Python中的類: 

  1)Class中,包括屬性、方法,它們都是public的。在Python的Class中,是不存在private,protected等修飾符的。

  2)__init__是構造函數,調用構造器時,會自動調用__init__。它相當於Java中的<init>。在創建一個Python對象時,不需要像Java那樣使用new。

  3)__del__是析構函數,當del instance時,會自動調用__del__。它相當於Java中的finalize

  4)需要獲取對象的字元串表示時,會調用__str__。它就相當於Java中的toString。

  5)類的方法的第一個參數,都是self,相當於Java中的this。其實Java中的實例方法的第一個參數也是this,只是被隱藏了而已,如果你瞭解JVM 運行時的話,或者使用過 javassist或者asm等位元組碼工具的話,會知道的。上面的示例中的p1.show()運行時,可以理解為執行的是Person.show(p1)。 並不是說必須得寫成self,你也可以寫完this或者其他任何的滿足變數命名的形式。但通常大家都約定俗稱的寫為self,保持編碼風格的統一,有利於方便他人理解代碼。

  6)__init__,__del__,__str__不是必須的。

  7)所有屬性都要有初始值

 

2、Class getter,setter

  Java,JavaScript ES6都支持setter,getter。Python中也是支持的。

class Person(object):
    id=''
    name = ''
    age = 3
    
    # 等同於Java中的<init>,即構造器
    def __init__(self, id, name, age):
        print("init a Person instance")
        self.id = id
        self.name = name
        self.age = age

    def show(this):
        print(this)
    #    print(this.toString())

   #def toString(self):        
   #   return "id:{}, name:{}, age:{}".format(self.id, self.name, self.age)
    
    # 等同於Java中的toString
    def __str__(self):
   #   return self.toString()
        return "id:{}, name:{}, age:{}".format(self.id, self.name, self.age)
    

    # 等同於Java中的finalize方法,del 實例時調用
    def __del__(self):
        print("finally a Person instance")
        self.id = None
        self.name = None
        self.age = None
        self = None

    def __get__(self, name):
        print("invoke in __get__")
        print(self.__dict__)
        return 1111

    def __getattr__(self, name):
        print("invoke in __getattr__")
        return 1111

    def __getattribute__(self, name):
        print("invoke in __getattribute__")
        print(object.__getattribute__(self, name))
        print("after invoke in __getattribute__")
        return object.__getattribute__(self, name)

  對於舊式類,訪問屬性的順序是: 

  1)直接訪問屬性

  2)訪問__getattr__

  對於新式類,訪問屬性的順序是:

  1)__getattribute

  2)直接訪問屬性

  3)__getattr__

  切記,如果寫了__getattribute__,最後一句話必須是object.__getattribute(self,name) 否則就會出現:’XxxType’ object is not callable 。它的存在,更像是作為攔截器使用。

3、Class繼承

  C++是多繼承的,Java是單繼承的,Python借鑒了C++的多繼承方式。

  在繼承結構下,訪問屬性,方法時,與Java中一樣的,先自己的,自己沒有時,才去從父類找。

  由於支持多繼承,所以當一個屬性、方法,在多個父類中都存在時,會訪問到哪個呢?

  要解答這個問題,就得先知道搜索屬性、方法的順序。採用的搜索演算法是深度優先搜索演算法。

  也就是一個class A(S1,S2,S3):pass; 要調用一個屬性時,會先從A里找,找不到再從S1,如果還找不到再從S2,依次類推。

 

  那麼在多繼承情況下,如果A,S1,S2,S3都重寫了__getattr__方法,那會有什麼區別呢?查找順序大體不變的:

  1)  A的直接屬性,找不到然後是A.__getattr__

  2)  S1的直接屬性,找不到然後是S1.__getattr__

  3)  S2的直接屬性,找不到然後是S2.__getattr__

  4)  S3的直接屬性,找不到然後是S3.__getattr__

 

  對於構造函數__init__,在構造實例時,不會像Java那樣,先去調用父類的__init__。

class Student(Person):
    def __init__(self, id, name, age,email):
        print("invoke in Student __init__")
        super(Student, self).__init__(id, name, age)
        self.email = email

 

  Java中有super(),Python中是否有呢?能否利用super呢?如果不能自動調用父類的構造器,那麼在重寫__init__又得給所有的屬性都分配一下,這個好麻煩的,該怎麼辦呢?只能以編程的方式自己調用了。

   super(類,instance),這個函數的作用是找到指定的類的下一個父類的指定方法,將該方法在指定的實例上調用。

     例如上面的例子中,繼承關係是這樣的:Student > Person > object。self是Student對象,super(Student, self).__init__(id, name, age)該語句的意思就是:找到Student的下一個父類(即Person)的__init__方法,然後在self上調用該__init__方法。

 

  需要註意的是:

  1super函數的兩個參數,不能有誤。需要滿足兩個條件,第二個instance應該是第一個參數所代表的類的實例(或者是其子類的實例)。

  2)Super只能在新式類中使用。

 

 

4、運算符重寫

  在.Net和Scala編程語言中,都是支持運算符重寫的。如果沒有接觸過這些東西,可能會費解的。其實只要把運算符看著是方法就可以了。從這個角度來理解的話,Java也是支持運算符重寫的,只不過呢,該特性並沒有暴露給用戶罷了。例如字元串拼接 + ,它其實是調用的StringBuilder.append方法,遍歷集合的foreach,它其實調用的是iterator。既然提到了運算符重寫,那麼Python中也必然是支持的,並且它把這個特性暴露出來了。

 

  Python String 就重寫了幾個運算符:

+ 字元串拼接
* copy多份
== 比較字元串內容
> 字元串比較
< 字元串比較

  那麼怎樣實現運算符重寫呢? 

  上面已經說明,將運算符看作是一個方法。那麼重寫運算符,就是就是重寫方法了。

  下麵列出了常見的運算符重載:

重載方法

說明

調用

__init__

構造器

對象建立,X=Class()

__del__

析構方法

對象回收,或者del X

__add__

運算符 +

X+Y, X+=Y

__iadd__

增強的 +

X+Y, X+=Y

__radd__

左側+

Noninstance + Y

__or__

運算符 | (位 OR)

X|Y, X|=Y

__repr__,__str__

列印,轉換

print(X), repr(X),str(X)

__getattr__

點號運算符

獲取屬性

__setattr__

賦值運算符

設置屬性

__call__

函數調用

Y()

__len__

長度

len(X)

__cmp__,

__lt__,

__eq__

比較

X < Y

X==Y

__getitem__

索引運算符

X[name]

__setitem__

索引賦值

X[Y]=Z

__iter__

迭代

迴圈,迭代等

 

  使用__getitem__可以使得對象具備索引的方式來訪問?

  測試如下:對上面的Student如下:

 

class Student(Person):
    def __init__(self, id, name, age,email):
        print("invoke in Student __init__")
        super(Student, self).__init__(id, name, age)
        self.email = email


    def __getitem__(self, name):
        return self.__dict__[name] + "_suffix"

  執行測試: 

  

import model
Student = model.Student
s = Student('0001', 'fjn', 20, '[email protected]')
s.show()
print(s["email"])

  發現結果是:[email protected]_suffix 

 

5、模擬私有屬性

  通過上面的學習,瞭解到Python的屬性、方法都是public, 這點和JavaScript太 一樣了。寫Java時間久了,私有屬性的好處,怎麼可以浪費了呢。那麼如何模擬出私有的?

有兩種方式可以模擬的,都與JavaScript里的理念是類似的。

  方式一:使用對象時,直接加屬性。

  方式二:利用對象的__dict__

 

6、Static Method

  在java中,會將實例方法與類方法區分,具體做法是在 class 方法上加上static修飾符。在python中是沒有static的,那麼如何實現static方法。

  前面也講了,實例方法聲明時,第一個參數是self。在python中,實例方法本質就是調用類方法的。  

p1=Person(‘a’,’b’,23)
Person.show(p1)

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 八、課程詳情頁功能的實現 8.1.課程列表 (1)配置urls MxOnline/urls中 course裡面新建urls.py 把course-list.html拷貝到templates目錄下 (2)course-list.html繼承base.html 修改title,修改bread裡面,con ...
  • 由於前端資源緊缺,我的後端系統遲遲等不來它的前端,沒辦法只好自己來寫了。從html,js入門學起,然後照著vue.js的官方教程寫了幾個實例,從github上clone了一個不錯的vue.js模版,填充了一個星期。雖然界面有些醜,但是總算是走通了全部的業務,期間被跨域,跳轉,cookie等問題折磨得 ...
  • 一.dom4j的簡介 dom4j是一個Java的XML API,是jdom的升級品,用來讀寫XML文件的。dom4j是一個十分優秀的JavaXML API,具有性能優異、功能強大和極其易使用的特點,它的性能超過sun公司官方的dom技術,同時它也是一個開放源代碼的軟體,可以在SourceForge上 ...
  • 本文實例講述了jQuery實現購物車計算價格功能的簡易方法,做的比較簡單,現分享給大家供大家參考。具體如下: 目的: 1 <%@ page language="java" contentType="text/html; charset=utf-8" 2 pageEncoding="utf-8"%> ...
  • L1-013. 計算階乘和 時間限制 400 ms 記憶體限制 65536 kB 代碼長度限制 8000 B 判題程式 Standard 作者 陳越 時間限制 400 ms 時間限制 400 ms 記憶體限制 65536 kB 記憶體限制 65536 kB 代碼長度限制 8000 B 代碼長度限制 800 ...
  • 1 學習計劃 1、定區關聯客戶 n 完善CRM服務中的客戶查詢方法 n 在BOS項目中配置代理對象遠程調用crm服務 n 調整定區關聯客戶頁面 n 實現定區關聯客戶 2、查看定區中包含的分區 n 頁面調整 n 服務端實現 3、查看定區關聯的客戶列表數據 n 頁面調整 n 服務端通過代理對象遠程調用C ...
  • package com.ij34; import us.codecraft.webmagic.Site; import us.codecraft.webmagic.Page; import us.codecraft.webmagic.Spider; import us.codecraft.webma... ...
  • 轉載自 https://blog.csdn.net/u012609509/article/details/70230204 Python中的幾種矩陣乘法 1. 同線性代數中矩陣乘法的定義: np.dot() np.dot(A, B):對於二維矩陣,計算真正意義上的矩陣乘積,同線性代數中矩陣乘法的定義 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...