(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.rhkb.cn/news/375290.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Data-Juicer:阿里巴巴荣誉出品的大模型数据清洗框架

Diffusion Models专栏文章汇总:入门与实战 前言:如何优雅地进行大规模数据清洗是一门艺术,特别对于大模型,数据的质量是决定模型成功最关键的因素之一。阿里巴巴最近开源了一项专门针对大语言模型和视频生成大模型的数据清洗框架,值得关注! 目录 主要特点 数据处理 分…

通过 tomcat 让手机访问到电脑写的 html 网页

之前实现的 html 小项目只能在自己的电脑上展示,如果要在其他电脑或者在手机上就看不到网页了 想要在手机上访问自己写的网页,我们可以借助 tomcat 首先我们可以从官网下载 tomcat 官网链接:apache官网 我们拉到最底部,找到 a…

【观成科技】Websocket协议代理隧道加密流量分析与检测

Websocket协议代理隧道加密流量简介 攻防场景下,Websocket协议常被用于代理隧道的搭建,攻击者企图通过Websocket协议来绕过网络限制,搭建一个低延迟、双向实时数据传输的隧道。当前,主流的支持Websocket通信代理的工具有&#xf…

详细谈谈负载均衡的startupProbe探针、livenessProbe探针、readnessProbe探针如何使用以及使用差异化

文章目录 startupProbe探针startupProbe说明示例配置参数解释 使用场景说明实例——要求: 容器在8秒内完成启动,否则杀死对应容器工作流程说明timeoutSeconds: 和 periodSeconds: 参数顺序说明 livenessProbe探针livenessProbe说明示例配置参数解释 使用…

centos9+mysql8.0下mycat1.6部署

#创作灵感# 整理一下mysql代理技术,这个当时是和mysql集群部署一个项目的,一并整理出来供参考。 1、环境准备 此处使用的为M-M-SS双主双从结构集群,集群部署方法放在我的上一篇文章中 防火墙可以使用firewall-cmd放行,演示环境…

Linux /etc/profile 详解

概述 Linux是一个多用户的操作系统。每个用户登录系统后,都会有一个专用的运行环境。通常每个用户默认的环境都是相同的,这个默认环境实际上就是一组环境变量的定义。用户可以对自己的运行环境进行定制,其方法就是修改相应的系统环境变量&…

化繁为简!新一代 Anybus 网关为何简单易用?

为什么易用性很重要? 产品的易用性一直至关重要,它直接影响用户满意度和市场接受度。近年来,随着自动化设备数量的迅速增长,自动化工程师的工作量大幅增加,使得用户对易用性的要求日益提高。 自动化工程师面临的主要…

BGP第二日

上图为今日所用拓扑 ,其中R1和R4,R3和R5为EBGP邻居,R1和R3为IBGP邻居,AS200区域做OSPF动态路由 一.BGP建立邻居的六种状态 1.idle 空闲状态:建立邻居最初的状态 2.Connect 连接状态:在…

解决GPT-4o耗电难题!DeepMind新算法训练效率提升13倍,能耗降低10倍!

目录 01 有更好的解决方案吗? 02 从“超级batch”中筛选数据 03 技术介绍 04 实验结果 生成可学习batch 谷歌DeepMind推出的新算法JEST,将LLM训练的迭代次数减少了13倍,计算量降低了10倍,有望重塑AI未来。GPT-4o早已成为耗能…

linux 0.11 中的重要的全局变量

通过对全局变量的了解,也有助于了解整个代码的逻辑。就跟学习类一样,了解类有哪些成员变量,也有助于了解类的成员函数的功能。 (1)内存初始化相关 static u_char mem_map [ PAGING_PAGES ] { 0 , } .本数组对 1M 以外…

数据结构 —— BellmanFord算法

数据结构 —— BellmanFord算法 BellmanFord算法检测负权值环BellmanFord和Dijkstra思想上的区别Dijkstra算法的思想Bellman-Ford算法的思想思想上的对比 我们今天来看一个算法BellmanFord算法,我们之前的Dijkstra算法只能用来解决正权图的单源最短路径问题。 Bell…

06浅谈大语言模型可调节参数TopP和TopK

浅谈大模型参数TopP和TopK 大语言模型中的temperature、top_p和top_k参数是用来控制模型生成文本时的随机性和创造性的。下面分享一下topP和topK两个参数的意义及逻辑; top K(Top-K Sampling) 作用:只从模型认为最可能的k个词中选…

Nodejs 第八十四章(ElasticSearch搜索)

ElasticSearch基本用法在之前的篇章介绍过了 这里不在过多阐述 模拟假数据 安装库 faker-js/faker 模拟假数据的一个库非常好用支持中文使用中文 locale: [zh_CN], 设置即可生成名字,邮箱,手机号,id,年龄,性别生成完成…

Python功能制作之获取CSDN所有发布文章的对应数据

大家好,今天我要分享的是一个实用的Python脚本,它可以帮助你批量获取CSDN博客上所有发布文章的相关数据,并将这些数据保存到Excel文件中。此外,脚本还会为每篇文章获取一个质量分,并将这个分数也记录在Excel中。让我们…

LLM-阿里云 DashVector + ModelScope 多模态向量化实时文本搜图实战总结

文章目录 前言步骤图片数据Embedding入库文本检索 完整代码 前言 本文使用阿里云的向量检索服务(DashVector),结合 ONE-PEACE多模态模型,构建实时的“文本搜图片”的多模态检索能力。整体流程如下: 多模态数据Embedd…

HTML5新增的input元素类型:number、range、email、color、date等

HTML5 大幅度地增加与改良了 input 元素的种类,可以简单地使用这些元素来实现 HTML5 之前需要使用 JavaScript 才能实现的许多功能。 到目前为止,大部分浏览器都支持 input 元素的种类。对于不支持新增 input 元素的浏览器,input 元素被统一…

采购订单列表根据条件设置行背景色

文章目录 采购订单列表根据条件设置行背景色Python实现Bos配置实现-列表条件格式化 采购订单列表根据条件设置行背景色 Python实现 python脚本 import clr clr.AddReference(System) clr.AddReference(Kingdee.BOS) clr.AddReference(Kingdee.BOS.Core) clr.AddReference(Sy…

spark shuffle写操作——SortShuffleWriter

写入的简单流程: 1.生成ExternalSorter对象 2.将消息都是插入ExternalSorter对象中 3.获取到mapOutputWriter,将中间产生的临时文件合并到一个临时文件 4.生成最后的data文件和index文件 可以看到写入的重点类是ExternalSorter对象 ExternalSorter 基…

高创新 | CEEMDAN-VMD-GRU-Attention双重分解+门控循环单元+注意力机制多元时间序列预测

目录 效果一览基本介绍模型设计程序设计参考资料 效果一览 基本介绍 高创新 | CEEMDAN-VMD-GRU-Attention双重分解门控循环单元注意力机制多元时间序列预测 本文提出一种基于CEEMDAN 的二次分解方法,通过样本熵重构CEEMDAN 分解后的序列,复杂序列通过VMD…

算法日常练习

对于这个题&#xff0c;如何处理同一个方向的问题&#xff0c;且对于同一组的如果间隔太大如何实现离散化 #include<bits/stdc.h> using namespace std;#define int long long typedef long long ll; map<pair<int,int>,vector<pair<ll,ll>>> mp…