爆款云主机2核4G限时秒杀,88元/年起!
查看详情

活动

天翼云最新优惠活动,涵盖免费试用,产品折扣等,助您降本增效!
热门活动
  • 618智算钜惠季 爆款云主机2核4G限时秒杀,88元/年起!
  • 免费体验DeepSeek,上天翼云息壤 NEW 新老用户均可免费体验2500万Tokens,限时两周
  • 云上钜惠 HOT 爆款云主机全场特惠,更有万元锦鲤券等你来领!
  • 算力套餐 HOT 让算力触手可及
  • 天翼云脑AOne NEW 连接、保护、办公,All-in-One!
  • 中小企业应用上云专场 产品组合下单即享折上9折起,助力企业快速上云
  • 息壤高校钜惠活动 NEW 天翼云息壤杯高校AI大赛,数款产品享受线上订购超值特惠
  • 天翼云电脑专场 HOT 移动办公新选择,爆款4核8G畅享1年3.5折起,快来抢购!
  • 天翼云奖励推广计划 加入成为云推官,推荐新用户注册下单得现金奖励
免费活动
  • 免费试用中心 HOT 多款云产品免费试用,快来开启云上之旅
  • 天翼云用户体验官 NEW 您的洞察,重塑科技边界

智算服务

打造统一的产品能力,实现算网调度、训练推理、技术架构、资源管理一体化智算服务
智算云(DeepSeek专区)
科研助手
  • 算力商城
  • 应用商城
  • 开发机
  • 并行计算
算力互联调度平台
  • 应用市场
  • 算力市场
  • 算力调度推荐
一站式智算服务平台
  • 模型广场
  • 体验中心
  • 服务接入
智算一体机
  • 智算一体机
大模型
  • DeepSeek-R1-昇腾版(671B)
  • DeepSeek-R1-英伟达版(671B)
  • DeepSeek-V3-昇腾版(671B)
  • DeepSeek-R1-Distill-Llama-70B
  • DeepSeek-R1-Distill-Qwen-32B
  • Qwen2-72B-Instruct
  • StableDiffusion-V2.1
  • TeleChat-12B

应用商城

天翼云精选行业优秀合作伙伴及千余款商品,提供一站式云上应用服务
进入甄选商城进入云市场创新解决方案
办公协同
  • WPS云文档
  • 安全邮箱
  • EMM手机管家
  • 智能商业平台
财务管理
  • 工资条
  • 税务风控云
企业应用
  • 翼信息化运维服务
  • 翼视频云归档解决方案
工业能源
  • 智慧工厂_生产流程管理解决方案
  • 智慧工地
建站工具
  • SSL证书
  • 新域名服务
网络工具
  • 翼云加速
灾备迁移
  • 云管家2.0
  • 翼备份
资源管理
  • 全栈混合云敏捷版(软件)
  • 全栈混合云敏捷版(一体机)
行业应用
  • 翼电子教室
  • 翼智慧显示一体化解决方案

合作伙伴

天翼云携手合作伙伴,共创云上生态,合作共赢
天翼云生态合作中心
  • 天翼云生态合作中心
天翼云渠道合作伙伴
  • 天翼云代理渠道合作伙伴
天翼云服务合作伙伴
  • 天翼云集成商交付能力认证
天翼云应用合作伙伴
  • 天翼云云市场合作伙伴
  • 天翼云甄选商城合作伙伴
天翼云技术合作伙伴
  • 天翼云OpenAPI中心
  • 天翼云EasyCoding平台
天翼云培训认证
  • 天翼云学堂
  • 天翼云市场商学院
天翼云合作计划
  • 云汇计划
天翼云东升计划
  • 适配中心
  • 东升计划
  • 适配互认证

开发者

开发者相关功能入口汇聚
技术社区
  • 专栏文章
  • 互动问答
  • 技术视频
资源与工具
  • OpenAPI中心
开放能力
  • EasyCoding敏捷开发平台
培训与认证
  • 天翼云学堂
  • 天翼云认证
魔乐社区
  • 魔乐社区

支持与服务

为您提供全方位支持与服务,全流程技术保障,助您轻松上云,安全无忧
文档与工具
  • 文档中心
  • 新手上云
  • 自助服务
  • OpenAPI中心
定价
  • 价格计算器
  • 定价策略
基础服务
  • 售前咨询
  • 在线支持
  • 在线支持
  • 工单服务
  • 建议与反馈
  • 用户体验官
  • 服务保障
  • 客户公告
  • 会员中心
增值服务
  • 红心服务
  • 首保服务
  • 客户支持计划
  • 专家技术服务
  • 备案管家

了解天翼云

天翼云秉承央企使命,致力于成为数字经济主力军,投身科技强国伟大事业,为用户提供安全、普惠云服务
品牌介绍
  • 关于天翼云
  • 智算云
  • 天翼云4.0
  • 新闻资讯
  • 天翼云APP
基础设施
  • 全球基础设施
  • 信任中心
最佳实践
  • 精选案例
  • 超级探访
  • 云杂志
  • 分析师和白皮书
  • 天翼云·创新直播间
市场活动
  • 2025智能云生态大会
  • 2024智算云生态大会
  • 2023云生态大会
  • 2022云生态大会
  • 天翼云中国行
天翼云
  • 活动
  • 智算服务
  • 产品
  • 解决方案
  • 应用商城
  • 合作伙伴
  • 开发者
  • 支持与服务
  • 了解天翼云
      • 文档
      • 控制中心
      • 备案
      • 管理中心

      Python面向对象程序设计讲座【修订】

      首页 知识中心 软件开发 文章详情页

      Python面向对象程序设计讲座【修订】

      2025-02-26 07:21:05 阅读次数:11

      class,print,self,实例,方法,调用

      Python面向对象程序设计讲座【修订】

      概述

      面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想。OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。

      面向过程的程序设计把计算机程序视为一系列的命令集合,即一组函数的顺序执行。为了简化程序设计,面向过程把函数继续切分为子函数,即把大块函数通过切割成小块函数来降低系统的复杂度。

      而面向对象的程序设计把计算机程序视为一组对象的集合,而每个对象都可以接收其他对象发过来的消息,并处理这些消息,计算机程序的执行就是一系列消息在各个对象之间传递。

      【附、面向过程的程序设计、事件驱动程序设计、面向对象程序设计与函数式程序设计

      ☆面向过程的程序设计(Process oriented programming),也称为结构化程序设计(Structured programming),有时会被视为是指令式编程(Imperative programming)的同义语。。编写程序可以说是这样一个过程:从系统要实现的功能入手把复杂的任务分解成子任务,把子任务再分解成更简单的任务,层层分解来完成。可以采用函数(function)或过程(procedure)一步步细化调用实现。程序流程结构可分为顺序(sequence)、选择(selection)及重复(repetition)或循环(loop)。

      许多语言可以支持过程式程序设计,Python也可以, Python中不用类的常见的程序设计就是。

      ☆事件驱动程序设计(Event-driven programming)

      基于事件驱动的程序设计在图形用户界面(GUI)出现很久前就已经被应用于程序设计中,可是只有当图形用户界面广泛流行时,它才逐渐形演变为一种广泛使用的程序设计模式。

      在过程式的程序设计中,代码本身就给出了程序执行的顺序,尽管执行顺序可能会受到程序输入数据的影响。

      在事件驱动的程序设计中,程序中的许多部分可能在完全不可预料的时刻被执行。往往这些程序的执行是由用户与正在执行的程序的互动激发所致。

      事件驱动常常用于用户与程序的交互,通过图形用户接口(鼠标、键盘、触摸板)进行交互式的互动。属于事件驱动的编程语言有:VB、C#、Java(Java Swing的GUI)、Python基于tkinter的GUI编程等。

      事件(event)表示程序某件事发生的信号。事件分为:

      外部事件:由外部用户动作产生的事件。例如,点击鼠标、按键盘。

      内部事件:由系统内部产生的事件。例如,定时器事件。

      系统预定义一些事件类型如按键、点击、鼠标移动等,事件类型代表是什么事件。事件触发时可以运行事件处理代码。

      ☆面向对象程序设计(Object Oriented Programming),是围绕着问题域中的对象(Object)来设计,对象包含属性、方法。对象则指的是类的实例。它将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的重用性、灵活性和扩展性,对象里的程序可以访问及经常修改对象相关联的数据。在面向对象程序编程里,计算机程序会被设计成彼此相关的对象。

      面向对象程序设计可以看作一种在程序中包含各种独立而又互相调用的对象的思想,这与传统的思想刚好相反:传统的程序设计主张将程序看作一系列函数的集合,或者直接就是一系列对电脑下达的指令。面向对象程序设计中的每一个对象都应该能够接受数据、处理数据并将数据传达给其它对象,因此它们都可以被看作一个小型的“机器”,即对象。目前已经被证实的是,面向对象程序设计推广了程序的灵活性和可维护性,并且在大型项目设计中广为应用。此外,支持者声称面向对象程序设计要比以往的做法更加便于学习,因为它能够让人们更简单地设计并维护程序,使得程序更加便于分析、设计、理解。反对者在某些领域对此予以否认。

      当我们提到面向对象的时候,它不仅指一种程序设计方法。它更多意义上是一种程序开发方式、设计思想。在这一方面,我们必须了解更多关于面向对象系统分析和面向对象设计(Object Oriented Design,简称OOD)方面的知识。许多流行的编程语言是面向对象的,它们的风格就是会由对象来创出实例。

      面向对象(Object Oriented)它是一种设计思想。从20世纪60年代提出面向对象的概念到现在,它已经发展成为一种比较成熟的编辑思想。

      ☆函数式程序设计(functional programming),顺便指出,不要误认为使用了函数就是函数式程序设计。函数式程序设计(functional programming)或称函数编程,是一种编程范式(programming paradigm),它将电脑运算视为函数运算,并且避免使用程序状态以及易变对象。其中,λ演算(lambda calculus)为该语言最重要的基础,λ演算的函数可以接受函数当作输入(引数)和输出(传出值),主要思想是把运算过程尽量写成一系列嵌套的函数调用。举例来说,现在有这样一个数学表达式:

        (1 + 2) * 3 - 4

      传统的过程式编程,可能这样写:

        var a = 1 + 2;

        var b = a * 3;

        var c = b - 4;

      函数式编程要求使用函数,我们可以把运算过程定义为不同的函数,然后写成下面这样:

        var result = subtract(multiply(add(1,2), 3), 4);

      函数式编程允许把函数本身作为参数传入另一个函数,还允许返回一个函数!函数式编程强调没有"副作用"(side effect),意味着函数要保持独立,所有功能就是返回一个新的值,没有其他行为,尤其是不得修改外部变量的值。

      在函数式编程中,函数是第一类对象(first class),指的是函数与其他数据类型一样,处于平等地位,可以赋值给其他变量,也可以作为参数,传入另一个函数,或者作为别的函数的返回值。

      Python对面向过程、面向对象编程与函数式编程都支持,关于Python函数式编程可参见https:///zh-cn/3/howto/functional.html 】


      面向过程和面向对象编程的不同之处

      下面以一个例子来说明面向过程和面向对象在程序设计上的不同之处。

      处理学生的成绩情况,为突出重点对问题进行了简化。

      先看面向过程编程(也称为结构化程序设计)情况:

      可以用一个dict表示表示一个学生的成绩:

      std1 = { 'name': 'Michael', 'score': 98 }
      std2 = { 'name': 'Bob', 'score': 81 }

      def print_score(std):
          print('%s: %s' % (std['name'], std['score']))

      print_score(std1)
      print_score(std2)

      运行之,参见下图:

      Python面向对象程序设计讲座【修订】

      如果采用面向对象的程序设计思想,我们首选思考的不是程序的执行流程,而是Student这种数据类型应该被视为一个对象,这个对象拥有name和score这两个属性。如果要打印一个学生的成绩,首先必须创建出这个学生对应的对象,然后,给对象发一个print_score消息,让对象自己把自己的数据打印出来。

      定义一个类如下

      class Student(object):
          def __init__(self, name, score):
               = name
              self.score = score

          def print_score(self):
              print('%s: %s' % (, self.score))

      bart = Student('Michael',98)
      lisa = Student('Bob',81)
      bart.print_score()
      lisa.print_score()

      运行之,参见下图:

      Python面向对象程序设计讲座【修订】

      下面是python类和对象的简要思维导图:

      Python面向对象程序设计讲座【修订】

      python的类

      创建一个新类(class)意味着创建一个新的对象类型(type of object),从而允许创建一个该类型的新实例(instances)。 每个类的实例可以拥有保存自己状态的属性(attributes)。 一个类的实例也可以有改变自己状态的(定义在类中的)方法(methods)。

      在 Python 中,有两种有效的属性名称(attribute names):数据属性(data attributes)和方法(methods)。

      数据属性,也称为属性(attribute) 对应于 Smalltalk 中的“实例变量(instance variables)”,以及 C++ 中的“数据成员(data members)”。

      方法是“从属于”对象(object)的函数(function)。 

      先直观看了解一下python类成员

      Python面向对象程序设计讲座【修订】​

      实例变量(instance variable)用于每个实例的唯一数据。定义位置类中,所有函数内部:以“self.变量名”的方式定义的变量。
      类变量(class variable)用于类的所有实例共享的属性和方法。定义位置类中、所有函数之外。
      局部变量,对于OOP,是class的方法(class的函数)中且没有self.的变量,对于面向过程编程,是函数中的变量。【对于面向过程编程,还有全局变量——函数外的变量】

      下面给出类变量和实例变量示例

      class Dog:
          kind = 'canine'         #类变量
      def __init__(self, name):
          total=2  #局部变量
          = name    #实例变量

      下面给出类中方法示例
      class MyClass(object):
          # 实例方法
          def instance_method(self):
              print('instance method called', self)
          
          # 类方法
          @classmethod
          def class_method(cls):
              print('class method called', cls)
          
          # 静态方法
          @staticmethod
          def static_method():
              print('static method called')

      class C:
          def __init__(self):
              self._x = None

          @property
          def x(self):
              """I'm the 'x' property."""
              return self._x

          @x.setter
          def x(self, value):
              self._x = value

          @x.deleter
          def x(self):
              del self._x

      ☆成员变量也被称为数据成员,保存了类或对象的数据。

      ☆初始化方法是一种特殊的函数,即类中的__init__()方法,用于初始化类的成员变量。【注:相当于其它语言的构造函数,故也称为构造方法】

      ☆成员方法是在类中定义的函数。

      ☆property(特征、特性)是对类进行封装而提供的实现机制,可以提升类封装的灵活性。
       

      类方法可以划分为实例方法(普通方法)、类方法和静态方法。

      其表象区别是:

      类方法前用@classmethod修饰

      静态方法前用@staticmethod修饰

      不加任何修饰的就是实例方法(普通方法)

      【@classmethod 和 @staticmethod 都是函数装饰器】

      ☆实例方法(普通方法)

      普通方法是我们最常用的方法,它定义时最少要包含一个约定为self的参数,用于绑定调用此方法的实例对象(所谓绑定,即用实例调用的时候,不需要显式的传入)——当实例调用方法的时候,会默认(无需显示指明实例名)将实例本身传入到这个参数self。

      简单示例源码:

      #定义类
      class A():
          name = '类成员name'
          
          #定义(普通)方法
          def instance_method(self, x):
              print() #普通方法可以访问类成员
              print(x)
       
      a = A() #实例化类
      
      a.instance_method('Hi')

      运行输出:

      类成员name
      Hi

      ☆类方法

      类方法有一个特点,就是这个方法必须要有@classmethod来修饰。和实例方法类似,至少也要传一个参数,约定为cls,Python会自动将类本身绑定到这个参数上面。

      简单示例源码:

      #定义类
      class A(object):
          name = '类成员name'
       
          #定义类方法
          @classmethod   
          def class_method(cls, s):
              print()  # 类方法可以访问类成员
              print(s)
        
      a = A() #实例化类
      
      a.class_method('Hi')

      运行输出:

      类成员name
      Hi

      ☆静态方法

      静态方法是使用@staticmethod修饰的方法,它不能访问任何类属性和类方法,因为它不含self或cls这些特殊参数,因此也无法访问类或实例中的成员。

      简单示例源码:

      #定义类
      class A():
          name = '类成员name'
          
          #定义静态方法,静态方法不能访问类成员name,否则报错
          @staticmethod
          def static_method(b):
              print(b)
       
      a = A() #实例化类
      a.static_method('Hi')

      运行输出:

      Hi

      创建类

      使用 class 语句来创建一个新类,class 之后为类的名称并以冒号结尾,简化格式为:

      class ClassName[(父类名)]:

         '类的帮助信息'   #类文档字符串

         class_suite  #类体

      其中

      class 定义类的关键字,小写。

      ClassNam 你定义类的名称,应符合标识符要求。按照惯例类名通首字母常是大写。

      class_suite 组成类体的语句,可以使用空语句pass——不做任何事情。

      [(父类名)] 是可选的,父类名 即继承的父类名称。

      class 语句行尾有有一个英文冒号。

      面向对象最重要的概念就是类(Class)和实例(Instance),在类的内部,使用 def 关键字来定义一个方法,与一般函数定义不同,类方法必须包含参数 self, 且为第一个参数,self 代表的是类的实例。

      python类的实例化语法

      obj=ClassName(x,x)

      其中,obj是类的实例化对象,ClassName是类名,若类中有定义含有参数的初始化方法 __init__ (),括号还需要有初始化变量的实参。

      下面给出一个例子

      #类定义
      class people:
          #定义基本属性
          name = ''
          age = 0

          #定义私有属性,私有属性在类外部无法直接进行访问
          __weight = 0

          #定义构造方法
          def __init__(self,n,a,w):
               = n
              self.age = a
              self.__weight = w

          def speak(self):
              print("%s 说: 我 %d 岁。" %(,self.age))

      # 实例化类
      p = people('runoob',10,30)
      p.speak()
       

      运行之,参见下图:

      Python面向对象程序设计讲座【修订】​

      方法是定义在类中的函数。与函数的区别在于:

      定义方法时,方法的第一个形参有特别用途——表示调用该方法的实例对象,且调用时不需为之显式地提供实参,一般命名为self,也可以改用其它名称但不建议。
      调用方法时,系统自动将调用该方法的实例对象作为实参传递给第一个形参——不需为这个形参显式地提供实参,第一个实参会传递给第二个形参,第二个实参会传递给第三个形参,依次类推。

      类实例化后,可以使用其属性和方法,语法:即对象名.属性名或方法名。

      前面的例子的类中有一个名为 __init__() 的特殊方法(初始化方法/构造方法),是类的专有方法之一,该方法在类实例化时会自动调用,注意,__init__方法的第一个参数永远是self,表示创建的实例本身,因此,在__init__方法内部,就可以把各种属性绑定到self,有了__init__方法,在创建实例的时候,就不能传入空的参数了,必须传入与__init__方法匹配的参数,但self不需要传,Python解释器自己会把实例变量传进去。并且,self就指向创建的实例本身,self.__class__ 则指向类。参见下例:

      class Complex:
          #定义类的特殊方法,即构造方法
          def __init__(self, realpart, imagpart):
              self.r = realpart
              self.i = imagpart

          #定义类的方法
          def prt(self):
              print("self代表的是类的实例,代表当前对象的地址:",self)
              print("self.__class__指向类:",self.__class__)

      x = Complex(8.3, 10)   #实例化类
      print(x.r, x.i)
      x.prt()
       

      运行之,参见下图:

      Python面向对象程序设计讲座【修订】​

      python类中__init__( )方法说明:

      用于执行"实例对象的初始化工作",即对象创建后,初始化当前对象的属性,无返回值。格式:

      def  __init__ (self[,形参列表]):

            函数体

      例如

      def __init__(self, n, a):

          self.n = n

          self.a = a

      说明如下:

      ★__init__方法是一个特殊的方法(init是单词初始化initialization的省略形式)

      ★第一个参数都是self(习惯上就命为self,你也可以写成其它的东西,比如写成me也是可以的,这样的话下面的self.就要写成me.),这个self,表示对象本身,谁调用,就表示谁,调用时,不需为它指定实参。从第二参数开始均可设置变长参数、默认值等。

      ★self.n = n,表示赋值给对象属性,等号前后两个n是不同的两个变量,self.n是self的属性。

      _init__不能有返回值。

      ★在创建类时,我们可以手动添加一个 __init__() 方法,称为初始化方法,即便不手动为类添加任何构造方法,Python 也会自动为类添加一个仅包含 self 参数的构造方法,称为类的默认构造方法。

      此方法的方法名中,开头和结尾各有 2 个下划线,且中间不能有空格。

      __init__() 方法可以包含多个参数,但必须包含一个名为 self 的参数,且必须作为第一个参数。也就是说,类的构造方法最少也要有一个 self 参数。

      ★python类的初始化方法的调用示例

      # 定义类

      class Demo:

          # 手动为类添加构造方法

          def __init__(self, name, age, gender):

              print('构造方法被执行了。', name, age, gender)

       

          # 定义 info() 方法

          def info(self,):

              print('info() 方法被执行了。')

      Demo('李萌', 16, '女')  # 创建 Demo 类的对象,将会隐式调用构造方法并传入参数值

      demo = Demo('阿杰', 18, '男')  # 创建 Demo 类的对象,将会隐式调用构造方法并传入参数值

      运行结果:

      Python面向对象程序设计讲座【修订】​

      在类中是否使用了构造方法:__init__的区别
      以完成同一功能的代码为例来看
      先看在类中使用了构造方法情况:

      class RectangleA:
          """
          定义一个矩形类,
          需要长和宽两个参数,
          拥有计算周长和面积两个方法。    
          """
          def __init__(self, x, y):  #构造方法
              self.x = x
              self.y = y
              
          def getPeri(self):  #定义方法
              val = (self.x + self.y) * 2
              return val
          
          def getArea(self):  #定义方法
              val = self.x * self.y
              return val

      rect=RectangleA(3,4)  #实例化类需要为参数赋值

      print(rect.getPeri())  #调用方法getPeri不需要为参数赋值
      print(rect.getArea())  #调用方法getArea不需为参数要赋值

      注意:方法中用到的参数前有前缀self,实例化类时不需要为参数赋值。运行之,参见下图:

      Python面向对象程序设计讲座【修订】​​

      再看在类中不使用初始化方法情况:

      class RectangleB:
          """
          定义一个矩形类,
          需要长和宽两个参数,
          拥有计算周长和面积两个方法。    
          """
          def getPeri(self,x,y):  #定义方法
              val = (x + y) * 2
              return val
          
          def getArea(self,x,y):  #定义方法
              val = x * y
              return val

      rect=RectangleB()  #实例化类不需要为参数赋值

      print(rect.getPeri(3,4))  #调用方法getPeri需要为参数赋值
      print(rect.getArea(3,4))  #调用方法getArea需要为参数赋值 

      注意:实例化类时需要为参数赋值。运行之,参见下图:

      Python面向对象程序设计讲座【修订】​​

      【类的特殊方法(也叫魔法方法):

      __init__ : 初始化方法,在生成对象时调用

      __del__ : 释放对象时使用

      __repr__ : 打印,转换

      __setitem__ : 按照索引赋值

      __getitem__: 按照索引获取值

      __len__: 获得长度

      __cmp__: 比较运算

      __call__: 函数调用

      __add__: 加运算

      __sub__: 减运算

      __mul__: 乘运算

      ……

      Python内置类属性

      当创建一个类之后,系统就自带了一些属性,叫内置类属性。常见的内置类属性:

      __dict__ : 类的属性(包含一个字典,由类的数据属性组成)

      __doc__ :类的文档字符串

      __name__: 类名

      __module__: 类定义所在的模块(类的全名是'__main__.className',如果类位于一个导入模块mymod中,那么className.__module__ 等于 mymod)

      __bases__ : 类的所有父类构成元素(包含了一个由所有父类组成的元组)

      ……

      注意:前后分别有两个下划线!】

      类变量、实例变量、局部变量和全局变量

      类变量(class variable),也叫成员变量、类属性——定义在类中,并且在方法外的变量。

      实例变量(instance variable)也叫实例属性——在类中方法内通过self.变量名定义的变量。

      定义在类中的变量也称为属性,定义在类中的函数也称为方法。

      方法中加self的变量可以看成是类的属性,或者是特性。使用方法改变和调用属性,作用域是当前实例。方法中不加self的变量可以看成一个局部变量,作用域是当前函数,该变量不能被直接引用。

      全局变量:在模块内、在所有函数外面、在class外面,这就是全局变量。

      例、

      big_temp = '123456788'  # 全局变量
      class Test:
          global_temp = '123'     # 类变量
          def __init__(self):
              self.temp = '321'   # 实例变量
              mytemp = '345'      # 局部变量

      print(big_temp)
      print('-----------')

      t = Test()
      print(t.global_temp)

      print('-----------')
      print(t.temp)

      #想想为何用print(t.mytemp或print(mytemp)都出错

      运行之,参见下图:

      Python面向对象程序设计讲座【修订】​​

      现在我们介绍python类的一些细节

      没有继承其它类的类,会自动继承系统中object类。在Python3中,object是所有类的超类(或者说基类)。

      下面定义一个空语句类

      class MyClassA:
          pass  #空语句

      print(dir(MyClassA)) #dir() 使用Python 内置函数dir() ,列出对象的所有属性及方法。
       

      运行之,参见下图:

      Python面向对象程序设计讲座【修订】​​

      在python类中可以调用类自身的方法,调用方式:

          ⑴类的内部调用:self.<方法名>(参数列表)

          ⑵在类的外部调用:<实例名>.<方法名>(参数列表)

      注意:以上两种调用方法中,提供的参数列表中都不用包括self——定义类方法时必须包含一个参数,约定用self ,代表的是类的实例,但在调用时不必指明传入相应的参数。。

      python中可以在类外定义的函数——全局函数,将其赋值给类中局部变量也是可以的。例如

      def coord_chng(x,y):  #定义全局函数
          return (abs(x),abs(y))

      class Ant:  #定义类Ant
          def __init__(self,x=0,y=0):  #定义初始化方法__init__,并对两个形参初始化
              self.x = x
              self.y = y
              self.disp_point()  #调用类中的方法disp_point

          def move(self,x,y):  #定义方法或叫类函数move
              x,y = coord_chng(x,y)  #调用全局函数
              self.edit_point(x,y)  #调用类中的方法edit_point
              self.disp_point()  #调用类中的方法disp_point

          def edit_point(self,x,y):#定义方法或叫类函数edit_point
              self.x += x
              self.y += y

          def disp_point(self):  #定义方法或叫类函数disp_point
              print("当前位置:(%d,%d)" % (self.x,self.y)) 

      ant_a = Ant()  #将Ant类实例为ant_a
      ant_a.move(2,4)  #调用实例ant_a的方法move
      ant_a.move(-9,6)  #调用实例ant_a的方法move

      运行之,参见下图:

      Python面向对象程序设计讲座【修订】​​

      下面给出一个比较实用的例子,使用了tkinter,关于参见“Python基于tkinter的GUI编程”一讲。

      一个简单的带图形界面的计算器:

      源码如下

      """tkcalc.pyw 简单的计算器
      """
      import tkinter as tk

      class Calc(tk.Tk):
          """计算器窗体类"""
          def __init__(self):
              """初始化实例"""
              tk.Tk.__init__(self)
              self.title("计算器")
              self.memory = 0  # 暂存数值
              self.create()

          def create(self):
              """创建界面"""
              btn_list = ["C", "M->", "->M", "/",
                          "7", "8", "9", "*",
                          "4", "5", "6", "-",
                          "1", "2", "3", "+",
                          "+/-", "0", ".", "="]
              r = 1
              c = 0
              for b in btn_list:
                  self.button = tk.Button(self, text=b, width=5,
                                          command=(lambda x=b: (x)))
                  self.button.grid(row=r, column=c, padx=3, pady=6)
                  c += 1
                  if c > 3:
                      c = 0
                      r += 1
              self.entry = tk.Entry(self, width=24, borderwidth=2,
                                    bg="yellow", font=("Consolas", 12))
              self.entry.grid(row=0, column=0, columnspan=4, padx=8, pady=6)

          def click(self, key):
              """响应按钮"""
              if key == "=":  # 输出结果
                  result = eval(self.entry.get())
                  self.entry.insert(tk.END, " = " + str(result))
              elif key == "C":  # 清空输入框
                  self.entry.delete(0, tk.END)
              elif key == "->M":  # 存入数值
                  self.memory = self.entry.get()
                  if "=" in self.memory:
                      ix = self.memory.find("=")
                      self.memory = self.memory[ix + 2:]
                  self.title("M=" + self.memory)
              elif key == "M->":  # 取出数值
                  if self.memory:
                      self.entry.insert(tk.END, self.memory)
              elif key == "+/-":  # 正负翻转
                  if "=" in self.entry.get():
                      self.entry.delete(0, tk.END)
                  elif self.entry.get()[0] == "-":
                      self.entry.delete(0)
                  else:
                      self.entry.insert(0, "-")
              else:  # 其他键
                  if "=" in self.entry.get():
                      self.entry.delete(0, tk.END)
                  self.entry.insert(tk.END, key)

      if __name__ == "__main__":
          Calc().mainloop()
       

      运行之,参见下图:

      Python面向对象程序设计讲座【修订】​​

      Python中的封装、继承和多态

      下面简要介绍面向对象编程有三大重要特征:封装、继承和多态。
      ★封装(Encapsulation)
      封装是指将数据与具体操作的实现代码放在某个对象内部,使这些代码的实现细节不被外界发现,外界只能通过接口使用该对象,而不能通过任何形式修改对象内部实现,正是由于封装机制,程序在使用某一对象时不需要关心该对象的数据结构细节及实现操作的方法。使用封装能隐藏对象实现细节,使代码更易维护,同时因为不能直接调用、修改对象内部的私有信息,在一定程度上保证了系统安全性。类通过将函数和变量封装在内部,实现了比函数更高一级的封装。
      例
      class Student:
          classroom = '101'
          address = 'beijing' 

          def __init__(self, name, age):
              = name
              self.age = age

          def print_age(self):
              print('%s: %s' % (, self.age))


      # 类将它内部的变量和方法封装起来,阻止外部的直接访问
      # 以下是错误的用法,将报NameError: name 'xxx' is not defined
      #print(classroom)
      #print(address)
      #print_age()

      # 可以如下用
      stu=Student('张三','18') #实例化
      print(stu.classroom)
      print(stu.address)
      stu.print_age()


      ★继承(Inheritance)
      继承机制实现了代码的复用,多个类公用的代码部分可以只在一个类中提供,而其他类只需要继承这个类即可。
      在OOP程序设计中,当我们定义一个新类的时候,新的类称为子类(Subclass),而被继承的类称为基类、父类或超类(Base class、Super class)。继承最大的好处是子类获得了父类的全部变量和方法的同时,又可以根据需要进行修改、拓展。其语法结构如下:
      class Foo(superA, superB,superC....):
      class DerivedClassName(moduleName.BaseClassName):  ## 当父类定义在另外的模块(module)时

      继承示例
      # 父类定义
      class people:

          def __init__(self, name, age, weight):
              = name
              self.age = age
              self.__weight = weight

          def speak(self):
              print("%s 说: 我 %d 岁。" % (, self.age))

      # 继承
      class student(people):

          def __init__(self, name, age, weight, grade):
              # 调用父类的实例化方法
              people.__init__(self, name, age, weight)
              self.grade = grade

          # 重写父类的speak方法
          def speak(self):
              print("%s 说: 我 %d 岁了,我在读 %d 年级" % (, self.age, self.grade))

      s = student('ken', 10, 30, 3)
      s.speak()

       

      运行之,参见下图:

      Python面向对象程序设计讲座【修订】​​

      子类在调用某个方法或变量的时候,首先在自己内部查找,如果没有找到,则开始根据继承机制在父类里查找。

       

      Python是支持多继承。一个类继承多个父类,同时这些类都有相同的方法名,但是具有不同的方法体,这种多重继承情况下,新式类会按照广度优先查找(在Python3中所有的类都是新式类,我们这里只介绍新式类的多继承)。
      多重继承示例
      class A1(object): 
          def fun1(self):           
              print('A1_fun1') 

      class A2(object):
          def fun1(self): 
              print('A2_fun1') 

          def fun2(self): 
              print('A2_fun2') 

      class B1(A1,A2): 
           def fun2(self):
              print("B1_fun2")

      class B2(A1,A2): 
           pass
           

      class C(B1,B2): 
           pass 

      c=C() 
      c.fun1() # 实例c调用fun1()时,搜索顺序是 c->C->B1->B2->A1
      c.fun2() # 实例c调用fun2()时,搜索顺序是 c->C->B1

       

      运行之,参见下图:

      Python面向对象程序设计讲座【修订】​​

       

      本例的广度优先遍历示意图如下:

      Python面向对象程序设计讲座【修订】​​

       

      ★多态(Polymorphism)
      多态意味着可以对不同的对象使用同样的操作,但它们可能会以多种形态呈现出结果——不同的子类对象调用相同的父类方法,产生不同的执行效果。类的多态特性,需要满足以下 2 个前提条件:
      继承:多态一定是发生在子类和父类之间;
      重写:子类重写了父类的方法。

      例、
      class CLanguage:
          def say(self):
              print("调用的是 Clanguage 类的say方法")
              
      class CPython(CLanguage):
          def say(self):
              print("调用的是 CPython 类的say方法")
              
      class CLinux(CLanguage):
          def say(self):
              print("调用的是 CLinux 类的say方法")
              
      a = CLanguage()
      a.say()
      a = CPython()
      a.say()
      a = CLinux()
      a.say()

       

      运行之,参见下图:

      Python面向对象程序设计讲座【修订】​​

      可以看到,CPython 和 CLinux 都继承自 CLanguage 类,且各自都重写了父类的 say() 方法。从运行结果可以看出,同一变量 a 在执行同一个 say() 方法时,由于 a 实际表示不同的类实例对象,因此 a.say() 调用的并不是同一个类中的 say() 方法,这就是多态。

      Python 在多态的基础上,衍生出了一种更灵活的编程机制。为了领略 Python 类使用多态特性的精髓,对上面的程序进行改写:
      class WhoSay:
          def say(self,who):
              who.say()
              
      class CLanguage:
          def say(self):
              print("调用的是 Clanguage 类的say方法")
              
      class CPython(CLanguage):
          def say(self):
              print("调用的是 CPython 类的say方法")
              
      class CLinux(CLanguage):
          def say(self):
              print("调用的是 CLinux 类的say方法")
              
      a = WhoSay()
      #调用 CLanguage 类的 say() 方法
      a.say(CLanguage())
      #调用 CPython 类的 say() 方法
      a.say(CPython())
      #调用 CLinux 类的 say() 方法
      a.say(CLinux())

       

      运行之,参见下图:

      Python面向对象程序设计讲座【修订】​​

       
      此程序中,通过给 WhoSay 类中的 say() 函数添加一个 who 参数,其内部利用传入的 who 调用 say() 方法。这意味着,当调用 WhoSay 类中的 say() 方法时,我们传给 who 参数的是哪个类的实例对象,它就会调用那个类中的 say() 方法。

      版权声明:本文内容来自第三方投稿或授权转载,原文地址:https://blog.csdn.net/cnds123/article/details/108354860,作者:软件开发技术爱好者,版权归原作者所有。本网站转在其作品的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如因作品内容、版权等问题需要同本网站联系,请发邮件至ctyunbbs@chinatelecom.cn沟通。

      上一篇:【Linux】Linux 条件变量 为什么要配合互斥锁

      下一篇:【C++滑动窗口】3132. 找出与数组相加的整数 II|1620

      相关文章

      2025-05-19 09:04:44

      使用DoubleLinkedList扩展类,允许Add,Remove,Contains

      使用DoubleLinkedList扩展类,允许Add,Remove,Contains

      2025-05-19 09:04:44
      class , list , null , 扩展
      2025-05-14 10:33:16

      30天拿下Rust之向量

      在Rust语言中,向量(Vector)是一种动态数组类型,可以存储相同类型的元素,并且可以在运行时改变大小。向量是Rust标准库中的一部分,位于std::vec模块中。

      2025-05-14 10:33:16
      Rust , 使用 , 元素 , 向量 , 方法 , 索引 , 迭代
      2025-05-14 10:33:16

      30天拿下Rust之字符串

      在Rust中,字符串是一种非常重要的数据类型,用于处理文本数据。Rust的字符串是以UTF-8编码的字节序列,主要有两种类型:&str和String。其中,&str是一个对字符数据的不可变引用,更像是对现有字符串数据的“视图”,而String则是一个独立、可变更的字符串实体。

      2025-05-14 10:33:16
      amp , Rust , str , String , 使用 , 字符串 , 方法
      2025-05-14 10:33:16

      30天拿下Rust之泛型

      在Rust语言中,泛型是一种强大的工具,它允许我们编写可复用且灵活的代码。通过泛型,我们可以创建适用于多种类型的数据结构和函数,而无需为每种类型都重复编写相同的逻辑。在Rust中,泛型通过指定类型参数来实现,这些类型参数会在编译时被具体类型所替换。

      2025-05-14 10:33:16
      Rust , 参数 , 实例 , 泛型 , 示例 , 类型
      2025-05-14 10:03:13

      AJAX-事件循环(超详细过程)

      JS有一个基于事件循环的并发模型,事件循环负责执行代码、收集和处理事件以及执行队列中的子任务。

      2025-05-14 10:03:13
      代码 , 任务 , 出栈 , 异步 , 执行 , 调用 , 队列
      2025-05-14 10:03:05

      C++ 11新特性之bind

      std::bind是C++ 11中<functional>头文件提供的一个函数模板,它允许我们将函数或成员函数与其部分参数预先绑定在一起,形成一个新的可调用对象(英文为:Callable Object)。

      2025-05-14 10:03:05
      bind , std , 函数 , 参数 , 对象 , 绑定 , 调用
      2025-05-14 10:03:05

      30天拿下Rust之HashMap

      HashMap,被称为哈希表或散列表,是一种可以存储键值对的数据结构。它使用哈希函数将键映射到存储位置,以便可以快速检索和更新元素。

      2025-05-14 10:03:05
      HashMap , 使用 , 哈希 , 引用 , 方法 , 遍历 , 键值
      2025-05-14 10:02:58

      C++ 11新特性之function

      C++ 11标准库引入了许多创新功能,其中之一便是std::function。作为函数对象容器,std::function允许开发者在编译时不知道具体类型的情况下,存储和传递任意可调用对象,极大地提升了代码的灵活性和可复用性。

      2025-05-14 10:02:58
      function , std , 一个 , 函数 , 对象 , 调用 , 赋值
      2025-05-14 10:02:58

      30天拿下Rust之结构体

      在Rust语言中,结构体是一种用户自定义的数据类型,它允许你将多个相关的值组合成一个单一的类型。结构体是一种复合数据类型,可以用来封装多个不同类型的字段,这些字段可以是基本数据类型、其他结构体、枚举类型等。通过使用结构体,你可以创建更复杂的数据结构,并定义它们的行为。

      2025-05-14 10:02:58
      Rust , 使用 , 字段 , 实例 , 方法 , 示例 , 结构
      2025-05-14 10:02:58

      java休眠到指定时间怎么写

      java休眠到指定时间怎么写

      2025-05-14 10:02:58
      java , sleep , Thread , util , 方法
      查看更多
      推荐标签

      作者介绍

      天翼云小翼
      天翼云用户

      文章

      33561

      阅读量

      5265097

      查看更多

      最新文章

      30天拿下Rust之向量

      2025-05-14 10:33:16

      AJAX-事件循环(超详细过程)

      2025-05-14 10:03:13

      C++ 11新特性之bind

      2025-05-14 10:03:05

      C++ 11新特性之function

      2025-05-14 10:02:58

      java 判断map为null或者空

      2025-05-14 09:51:21

      python json反序列化为对象

      2025-05-14 09:51:15

      查看更多

      热门文章

      Python 函数调用父类详解

      2023-04-23 09:44:31

      Java中创建对象的方式

      2023-02-13 09:25:28

      java之十一 Java GUI

      2024-09-25 10:13:34

      Java学习之方法调用过程图解(理解)

      2023-04-06 06:35:24

      Java高级之类.class和类实例.getClass()

      2023-06-20 09:12:44

      qt调用外部程序(exe)

      2023-06-27 10:00:24

      查看更多

      热门标签

      java Java python 编程开发 代码 开发语言 算法 线程 Python html 数组 C++ 元素 javascript c++
      查看更多

      相关产品

      弹性云主机

      随时自助获取、弹性伸缩的云服务器资源

      天翼云电脑(公众版)

      便捷、安全、高效的云电脑服务

      对象存储

      高品质、低成本的云上存储服务

      云硬盘

      为云上计算资源提供持久性块存储

      查看更多

      随机文章

      经典面试题-线程状态

      Java静态变量在静态方法内部无法改变值

      Java中关于内部类的相关内容(上)

      C# 使用.NET性能计数器示例 绘制出正弦函数图像

      python面试题——Python中怎么通过反射来调用对象的函数?

      Python全网最全基础课程笔记(八)——字典,跟着思维导图和图文来学习,爆肝2w字,无数代码案例!

      • 7*24小时售后
      • 无忧退款
      • 免费备案
      • 专家服务
      售前咨询热线
      400-810-9889转1
      关注天翼云
      • 旗舰店
      • 天翼云APP
      • 天翼云微信公众号
      服务与支持
      • 备案中心
      • 售前咨询
      • 智能客服
      • 自助服务
      • 工单管理
      • 客户公告
      • 涉诈举报
      账户管理
      • 管理中心
      • 订单管理
      • 余额管理
      • 发票管理
      • 充值汇款
      • 续费管理
      快速入口
      • 天翼云旗舰店
      • 文档中心
      • 最新活动
      • 免费试用
      • 信任中心
      • 天翼云学堂
      云网生态
      • 甄选商城
      • 渠道合作
      • 云市场合作
      了解天翼云
      • 关于天翼云
      • 天翼云APP
      • 服务案例
      • 新闻资讯
      • 联系我们
      热门产品
      • 云电脑
      • 弹性云主机
      • 云电脑政企版
      • 天翼云手机
      • 云数据库
      • 对象存储
      • 云硬盘
      • Web应用防火墙
      • 服务器安全卫士
      • CDN加速
      热门推荐
      • 云服务备份
      • 边缘安全加速平台
      • 全站加速
      • 安全加速
      • 云服务器
      • 云主机
      • 智能边缘云
      • 应用编排服务
      • 微服务引擎
      • 共享流量包
      更多推荐
      • web应用防火墙
      • 密钥管理
      • 等保咨询
      • 安全专区
      • 应用运维管理
      • 云日志服务
      • 文档数据库服务
      • 云搜索服务
      • 数据湖探索
      • 数据仓库服务
      友情链接
      • 中国电信集团
      • 189邮箱
      • 天翼企业云盘
      • 天翼云盘
      ©2025 天翼云科技有限公司版权所有 增值电信业务经营许可证A2.B1.B2-20090001
      公司地址:北京市东城区青龙胡同甲1号、3号2幢2层205-32室
      • 用户协议
      • 隐私政策
      • 个人信息保护
      • 法律声明
      备案 京公网安备11010802043424号 京ICP备 2021034386号