(8)揭示Python編程精髓:深潛繼承與多態的奇幻之旅

目錄

  • 1. 命名空間與作用域
    • 1.1 命名空間概述
    • 1.2 作用域
    • 1.2.1 局部作用域
    • 1.2.2 全局作用域
    • 1.2.3 修改全局變量
    • 1.2.4 嵌套作用域
  • 2. 繼承
  • 3. 多態(Polymorphism)

1. 命名空間與作用域

1.1 命名空間概述

命名空間是一個從名字到對象的映射,它在Python程序中定義了一系列變量的名稱。每個命名空間都是一個字典的實現,雖然字典是直接由用戶創建的,但是命名空間的創建和使用完全由解釋器來控制。
在這里插入圖片描述

1.2 作用域

在Python編程中,作用域(Scope)是指程序中定義變量的區域,決定了變量的可見性和生命周期。它規定了程序中哪些區域能夠訪問特定的變量名稱。

Python中的作用域主要有四種:

  • 內置作用域(Built-in Scope):內置作用域包含了Python內置的函數和異常類,以及內置的函數和異常名(如abs(), int(), list(), Exception等)。這個作用域在Python解釋器啟動時創建,每個模塊都可以訪問內置作用域。
    然而,在Python中,我們通常不會直接提及“內置作用域”(Built-in Scope)作為一個獨立的作用域級別,盡管技術上內置名稱(如內置函數和異常等)確實存在于一個特定的命名空間中。然而,當我們討論作用域時,我們通常指的是全局作用域、局部作用域和(可能的)嵌套作用域。

  • 局部作用域(Local Scope):局部作用域是在函數或方法內部定義的變量的作用域。函數參數和函數內部定義的變量都屬于局部作用域。局部變量在函數調用時創建,在函數返回時銷毀。

  • 全局作用域(Global Scope):全局作用域是最外層的命名空間,在模塊級別定義的變量屬于全局作用域。全局作用域在程序執行時創建,程序的所有模塊都可以訪問全局作用域中的變量。

  • 嵌套作用域(Enclosing Scope):在嵌套函數中,外部函數定義的變量對內部函數而言是可見的,但僅當內部函數沒有定義同名的局部變量時。這個作用域在嵌套函數或類定義時創建。

在Python中,變量的訪問遵循LEGB規則,即Local(局部作用域)-> Enclosing(嵌套作用域,如果有的話)-> Global(全局作用域)-> Built-in(內置作用域)。這意味著,在查找一個變量時,Python會首先在當前的作用域中查找,如果找不到,它會向上一級作用域查找,直到找到為止或者引發NameError

需要注意的是,Python中沒有塊級作用域(Block Scope),也就是說,在ifforwhile語句塊中定義的變量,實際上是定義在包含該語句塊的函數或模塊的全局作用域或局部作用域中。這是與其他一些編程語言(如C++或Java)不同的地方。

1.2.1 局部作用域

在Python中,局部作用域通常指的是在函數內部定義的變量所存在的作用范圍。這些變量只能在定義它們的函數內部被訪問。當函數被調用時,這些局部變量被創建,并在函數執行完畢后被銷毀。

為了說明局部作用域在金融領域的應用,我們可以考慮一個簡單的例子:
一個計算復利(Compound Interest)的函數。在這個函數中,我們將使用局部變量來存儲如利率(interest rate)、本金(principal amount)、年份(years)和計算結果(future value)等信息。

def calculate_compound_interest(principal, annual_interest_rate, years):# 這些變量是局部變量,只能在calculate_compound_interest函數內部訪問# 假設一年有365天,這是為了簡化計算(實際中應考慮閏年等情況)days_in_year = 365# 將年利率轉換為日利率daily_interest_rate = annual_interest_rate / (100 * days_in_year)# 使用復利公式計算未來的價值future_value = principal * ((1 + daily_interest_rate) ** (days_in_year * years))# 返回計算結果return future_value# 示例:計算10000元本金在5%年利率下,10年后的復利
principal = 10000
annual_interest_rate = 5
years = 10
result = calculate_compound_interest(principal, annual_interest_rate, years)
print(f"未來的價值是: {result:.2f}元")

在這個示例中,days_in_yeardaily_interest_ratefuture_value都是局部變量。它們在calculate_compound_interest函數內部被定義和使用,并且在函數執行完畢后被銷毀。注意,這些變量在函數外部是不可見的(即不能從函數外部直接訪問)。這就是局部作用域的基本原理。

1.2.2 全局作用域

全局作用域是整個Python腳本中都可以訪問的作用域。在這里,我們將定義全局變量total_investmenttotal_return

示例:假設我們有一個投資組合,我們想要計算其投資回報率(ROI,Return on Investment)。我們可以定義全局變量來存儲投資的總金額和回報金額,然后在函數中計算ROI。

# 全局變量
total_investment = 100000  # 初始投資金額為10萬
total_return = 15000  # 假設回報金額為1萬5def calculate_roi():# 函數內部的計算將在局部作用域中進行roi = (total_return / total_investment) * 100  # 計算ROIprint(f"投資回報率為:{roi}%")# 調用函數,計算并打印ROI
calculate_roi()

在這個例子中,total_investmenttotal_return是全局變量,它們可以在全局作用域中被任何代碼訪問。我們在calculate_roi函數內部引用了這兩個全局變量來計算ROI。

1.2.3 修改全局變量

如果我們想在函數內部修改全局變量的值,我們需要使用global關鍵字來聲明。但是,在大多數情況下,最好避免在函數內部修改全局變量,因為這可能導致代碼更難理解和維護。不過,為了完整解釋,我們還是給出一個例子:

# 全局變量
total_investment = 100000  # 初始投資金額為10萬
total_return = 15000  # 假設回報金額為1萬5def update_investment_and_return(new_investment, new_return):global total_investment, total_returntotal_investment = new_investment  # 更新投資金額total_return = new_return  # 更新回報金額calculate_roi()  # 重新計算并打印ROI# 調用函數,更新投資金額和回報金額,并重新計算ROI
update_investment_and_return(120000, 20000)

在這個例子中,我們定義了一個新函數update_investment_and_return,它接受新的投資金額和回報金額作為參數,并使用global關鍵字聲明了要修改的全局變量。然后,它更新了這些全局變量的值,并重新計算了ROI。

1.2.4 嵌套作用域

在Python中,嵌套作用域通常與嵌套函數相關,即一個函數內部定義的另一個函數。在這種情況下,內部函數可以訪問其外部函數(即包含它的函數)的局部作用域中的變量,這被稱為封閉作用域或外部作用域。

下面是一個使用嵌套作用域和金融示例的Python代碼。我們將創建一個計算貸款支付金額的函數,并在其中定義一個嵌套的利率計算函數。

def calculate_monthly_payment(principal, annual_rate, term_years):# 將年利率轉換為月利率def calculate_monthly_rate(annual_rate):return annual_rate / 12 / 100# 嵌套函數內部使用外部函數的變量monthly_rate = calculate_monthly_rate(annual_rate)# 貸款期數(月份)total_payments = term_years * 12# 使用公式計算每月支付金額(這里簡化處理,沒有包含復雜的還款計算)# 注意:這里僅用于示例,真實情況中需使用專門的貸款公式monthly_payment = principal * monthly_rate / (1 - (1 + monthly_rate) ** -total_payments)return round(monthly_payment, 2)  # 保留兩位小數# 示例:計算50,000元的貸款在5%的年利率下,10年期限的每月支付金額
loan_amount = 50000
annual_interest_rate = 5
loan_term = 10
monthly_payment = calculate_monthly_payment(loan_amount, annual_interest_rate, loan_term)
print(f"每月需要支付: {monthly_payment} 元")

在上面的示例中,calculate_monthly_payment 函數是一個外部函數,它接收貸款本金、年利率和貸款期限(年)作為參數。這個函數內部定義了一個嵌套函數 calculate_monthly_rate,用于將年利率轉換為月利率。嵌套函數可以訪問其外部函數 calculate_monthly_payment 的作用域中的變量 annual_rate。然后,外部函數使用嵌套函數計算出的月利率來計算每月的支付金額,并返回結果。

注意,雖然嵌套函數在這里很有用,但它不是必需的。你也可以直接在 calculate_monthly_payment 函數中編寫計算月利率的代碼,而不是使用嵌套函數。但是,當邏輯變得更加復雜或者你需要將一部分邏輯封裝起來以便在多個地方重用時,嵌套函數就會非常有用。

2. 繼承

在Python中,繼承是一種面向對象編程的重要特性,它允許我們創建一個新的類(稱為子類或派生類),這個類繼承自一個或多個已存在的類(稱為父類或基類)。子類可以繼承父類的屬性和方法,并可以添加新的屬性和方法或重寫父類的方法。

在金融領域,繼承可以用于創建不同種類的金融產品類,例如,一個基本的金融產品類可以被繼承以創建具體的股票類、債券類、基金類等。下面是一個使用Python繼承及金融領域的示例。

# 定義一個基本的金融產品類
class FinancialProduct:def __init__(self, name, price):self.name = nameself.price = pricedef buy(self):print(f"購買了 {self.name},價格為 {self.price} 元。")def sell(self):print(f"出售了 {self.name},價格為 {self.price} 元(僅為示例,實際賣出價格可能不同)。")# 繼承自金融產品類的股票類
class Stock(FinancialProduct):def __init__(self, name, price, symbol):super().__init__(name, price)  # 調用父類的初始化方法self.symbol = symbol  # 股票特有的屬性:股票代碼def dividend(self, amount):print(f"股票 {self.name} (代碼 {self.symbol}) 分紅 {amount} 元。")# 創建一個股票對象并測試其方法
if __name__ == "__main__":apple_stock = Stock("蘋果公司股票", 150.0, "AAPL")apple_stock.buy()apple_stock.sell()apple_stock.dividend(3.0)# 嘗試使用基類的方法創建一個普通的金融產品(不是股票)bond = FinancialProduct("國債", 100.0)bond.buy()bond.sell()

在這個例子中,我們定義了一個FinancialProduct類作為基類,它包含了金融產品的一些通用屬性和方法,如name(產品名稱)、price(產品價格)、buy(購買)和sell(出售)。

然后我們定義了一個Stock類,它繼承自FinancialProduct類。Stock類添加了一個額外的屬性symbol(股票代碼)和一個新的方法dividend(分紅)。Stock類的__init__方法調用了父類FinancialProduct__init__方法以設置通用的屬性和方法,然后添加了Stock特有的屬性。

__main__部分,我們創建了一個Stock對象和一個FinancialProduct對象,并分別調用了它們的方法。這展示了子類如何使用繼承來重用父類的代碼,并添加自己的特定屬性和方法。

3. 多態(Polymorphism)

多態是面向對象編程的三大特性之一(繼承、封裝和多態),它意味著不同的對象對同一消息做出不同的響應。在Python中,多態性主要通過方法重寫(Overriding)和方法重載(Overloading,雖然Python本身不支持傳統的函數重載)來實現。

但是,在Python中,我們通常通過定義接口(通過抽象基類實現)或使用鴨子類型(duck typing)來實現多態性。

抽象基類允許你定義接口,子類可以繼承這些接口并實現所需的方法。而鴨子類型則是一種動態類型方式,它并不關心對象的類型,只關注對象是否擁有某些方法或屬性。

下面是一個使用Python的抽象基類和鴨子類型來展示金融領域多態性的示例:

首先,我們定義一個抽象基類FinancialProduct,它定義了一個計算回報率的接口:

from abc import ABC, abstractmethodclass FinancialProduct(ABC):@abstractmethoddef calculate_return(self):pass

接著,我們定義兩個具體的金融產品類Stock和Bond,它們繼承自FinancialProduct并實現了calculate_return方法:

class Stock(FinancialProduct):def __init__(self, name, current_price, purchase_price):self.name = nameself.current_price = current_priceself.purchase_price = purchase_pricedef calculate_return(self):return (self.current_price - self.purchase_price) / self.purchase_priceclass Bond(FinancialProduct):def __init__(self, name, face_value, coupon_rate, years_to_maturity):self.name = nameself.face_value = face_valueself.coupon_rate = coupon_rate / 100  # 將百分比轉換為小數self.years_to_maturity = years_to_maturitydef calculate_return(self):# 這里為了簡化,我們假設每年回報率是固定的return self.coupon_rate

現在我們可以定義一個函數來處理這些金融產品,這個函數不關心產品的具體類型,只要它實現了calculate_return方法即可:

def show_return(product):print(f"產品 {product.name} 的回報率為: {product.calculate_return() * 100:.2f}%")# 創建金融產品實例
stock = Stock("蘋果公司股票", 150.0, 100.0)
bond = Bond("五年期國債", 1000.0, 5.0, 5)# 調用函數,展示回報率
show_return(stock)
show_return(bond)

在這個例子中,show_return函數展示了多態性。它接受一個FinancialProduct類型的參數,但實際上可以接受任何實現了calculate_return方法的對象。這就是鴨子類型的體現:如果它走起路來像鴨子(即擁有calculate_return方法),那么我們就可以把它當作鴨子來處理。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/45021.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/45021.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/45021.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Qt:19.浮動窗口/子窗口(子窗口介紹、代碼方式創建子窗口、設置子窗口標題、為子窗口添加控件、設置子窗口停靠位置)

目錄 1.子窗口介紹: 2.代碼方式創建子窗口: 3.設置子窗口標題: 4.為子窗口添加控件: 5.設置子窗口停靠位置。 1.子窗口介紹: 在 Qt 中,可以創建和管理子窗口(子窗口體)以實現多窗…

圖片怎么制作成長期可用的活碼?掃碼提供圖片預覽的制作技巧

現在圖片的尺寸和清晰度的質量越來越高,相對應的會占用更多的存儲空間,現在很多人會將圖片存入云端后,通過生成二維碼的方式,掃碼來查看圖片內容。圖片轉換二維碼有利于將圖片分享給其他人查看,還能夠節省更多的空間&a…

SpringBoot自己開發一個starter

提示:本文主要講述如何自行開發一個SpringBoot的starter 文章目錄 目錄 文章目錄 前言 一、Starter是什么 二、創建一個SpringBoot項目 1.創建一個基本的SpringBoot項目 2.選擇要下載的庫 三、設置項目 1.提示 2.配置pom.xml 3.重點代碼 1.創建一個User類…

16.x86游戲實戰-匯編指令push pop pushad popad

免責聲明:內容僅供學習參考,請合法利用知識,禁止進行違法犯罪活動! 本次游戲沒法給 內容參考于:微塵網絡安全 工具下載: 鏈接:https://pan.baidu.com/s/1rEEJnt85npn7N38Ai0_F2Q?pwd6tw3 提…

【第29章】MyBatis-Plus之分頁插件

文章目錄 前言一、支持的數據庫二、配置方法三、屬性介紹四、自定義 Mapper 方法中使用分頁五、其他注意事項六、Page 類七、實戰1. 配置類2. 分頁類3. 測試 總結 前言 MyBatis-Plus 的分頁插件 PaginationInnerInterceptor 提供了強大的分頁功能,支持多種數據庫&a…

Windows電腦安裝Python結合內網穿透輕松搭建可公網訪問私有網盤

文章目錄 前言1.本地文件服務器搭建1.1.Python的安裝和設置1.2.cpolar的安裝和注冊 2.本地文件服務器的發布2.1.Cpolar云端設置2.2.Cpolar本地設置 3.公網訪問測試4.結語 前言 本文主要介紹如何在Windows系統電腦上使用python這樣的簡單程序語言,在自己的電腦上搭建…

kubernetes授予用戶指定命名空間的使用權限

kubernetes授予用戶指定命名空間的使用權限 問題描述具體實現簽發客戶端證書創建RBAC策略生成kubeconfig文件 問題描述 假如我們部門來了個新同事,他需要使用kubernetes集群,但是因為他剛來,還不熟悉,所以不能直接將kubernetes集…

Spring如何控制Bean加載+執行順序

1. Order 注解和 Ordered 接口 用途:控制組件執行順序或排序,但不控制Bean初始化順序。定義執行順序:通過整數值指定組件優先級,數值越小優先級越高。集合排序:影響自動裝配到集合中的組件排列順序。使用場景&#xf…

77.MySQL的分頁查詢

一、LIMIT關鍵字 LIMIT關鍵字用于限制返回結果集中的行數。其基本語法如下: SELECT * FROM 表名 LIMIT 行數; 例如,要從名為mark_info的表中選擇最新創建的10個工單的信息,可以執行以下查詢: SELECT * FROM mark_info ORDER B…

電力需求預測挑戰賽筆記 Taks1 跑通baseline

#AI夏令營 #Datawhale #夏令營 賽題 一句話介紹賽題任務可以這樣理解賽題: 【訓練時序預測模型助力電力需求預測】 電力需求的準確預測對于電網的穩定運行、能源的有效管理以及可再生能源的整合至關重要。 賽題任務 給定多個房屋對應電力消耗歷史 N 天的相關序列數…

拓撲排序(算法篇)

算法之拓撲排序 拓撲排序 概念: 拓撲排序是對有向無圈圖的頂點的一種排序。排序不必是唯一的,任何合理的排序都是可以的。具體做法是:先找出任意一個沒有入邊的頂點v(就是沒有其他頂點指向的頂點),將頂點v放入隊列,…

element-plus el-table點擊當前行和劃過展示鼠標

在 Element Plus 的 el-table 組件中,設置滑過行時鼠標的樣式可以通過 CSS 來實現。你可以使用 CSS 的 cursor 屬性來定義鼠標懸停時的樣式。以下是一個簡單的例子: 首先,在你的 Vue 組件的 .el-table .el-table__row:hover {cursor: poin…

09.AOP-尚硅谷Spring零基礎入門到進階,一套搞定spring6全套視頻教程(源碼級講解)

現有代碼缺陷 針對帶日志功能的實現類,我們發現有如下缺陷: 對核心業務功能有干擾,導致程序員在開發核心業務功能時分散了精力附加功能分散在各個業務功能方法中,不利于統一維護 解決思路 解決核心:解耦。把附加功能從…

glm-4 聯網搜索 api 測試

今天測試了一下 glm-4 的聯網搜索 web_search tool 調用,發現了 web_search 的網頁檢索返回結果中幾個比較詭異的事情,特此記錄: 有些檢索結果沒有 icon、link、media 字段,但從內容上看確實是聯網搜索出來的結果,不知…

從零開始讀RocketMq源碼(三)Broker存儲Message流程解析

目錄 前言 準備 消息載體CommitLog 文件持久化位置 源碼解析 broker消息對象MessageExtBrokerInner 異步存儲message CommitLog的真相 創建MappedFile文件 加入異步刷盤隊列 Message異步存儲MappedByteBuffer 總結 前言 在面試中我們經常會聽到這樣的回答&#x…

國產化趨勢下源代碼數據防泄密的信創沙盒的方案分享

隨著國產化的大力推進,越來越多的企事業單位在逐步替換Windows、Linux等操作系統的使用。那么什是國產化了?國產化是指在產品或服務中采用國內自主研發的技術和標注,替代過去依賴的他國的產品和服務,國產化又被稱之為“信創”&…

GitLab CI/CD實現項目自動化部署

1 GitLab CI/CD介紹 GitLab CI/CD 是 GitLab 中集成的一套用于軟件開發的持續集成(Continuous Integration)、持續交付(Continuous Delivery)和持續部署(Continuous Deployment)工具。這套系統允許開發團隊…

vue里實現點擊按鈕回到頁面頂部功能,博客必備!

效果 步驟 1-標簽結構 動態綁定樣式style&#xff0c;監聽點擊事件&#xff0c;后續控制opacity透明度。和滾動距離 <div class"toTop" :style"dynamicStyles" click"toTop"><!--<i class"fa fa-arrow-up"></i>…

Django ORM中的F 對象

F 對象非常強大&#xff0c;可以在查詢和更新操作中進行復雜的字段間運算。 假設我們有一個包含商品信息的模型 Product&#xff1a; from django.db import modelsclass Product(models.Model):name models.CharField(max_length100)price models.DecimalField(max_digits…

MySQL向自增列插入0失敗問題

問題 在一次上線時&#xff0c;發現通過腳本添加的狀態表中&#xff0c;待提交的狀態不正確&#xff0c;本來應該是0&#xff0c;線上是101。 原因 默認情況下&#xff0c;MySQL對應自增列&#xff0c;認為0和null等價&#xff08;因為mysql認為0不是最佳實踐不推薦使用&…