零基础学Python之面向对象

news2024/11/17 21:17:15

1.面向对象编程简介

(1)什么是面向对象

面向对象程序设计(Object Oriented Programming)作为一种新方法,其本质是以建立模型体现出来的抽象思维过程和面向对象的方法。模型是用来反映现实世界中事物特征的。任何一个模型都不可能反映客观事物的一切具体特征,只能对事物特征和变化规律的一种抽象,且在它所涉及的范围内更普遍、更集中、更深刻地描述客体的特征。通过建立模型而达到的抽象是人们对客体认识的深化。

Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的。

(2)面向对象技术简介

  • 类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
  • 类变量: 类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
  • 数据成员: 类变量或者实例变量, 用于处理类及其实例对象的相关的数据。
  • 方法重写: 如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
  • 局部变量: 定义在方法中的变量,只作用于当前实例的类。
  • 实例变量: 在类的声明中,属性是用变量来表示的。这种变量就称为实例变量,是在类声明的内部但是在类的其他成员方法之外声明的。
  • 继承: 即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。
  • 实例化: 创建一个类的实例,类的具体对象。
  • 方法: 类中定义的函数。
  • 对象: 通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。

(3)创建类语法

class ClassName:
   '类的帮助信息'   #类文档字符串
   class_suite  #类体
# 创建一个Person类,定义函数
class Person:
    def introduce_self(self):
        print("自定义函数")

# 实例化对象
person = Person()
person.introduce_self()

# 定义类名需要使用驼峰的命名方式。
# 通过id函数证明实例化出来的两个对象都是不同的
person1 = Person()
person2 = Person()
print(id(person1))
print(id(person2))

2.类的构造函数

构造函数,是一种特殊的方法,主要用来创建对象的时候去初始化对象,即为对象成员变量附初始值。

构造函数每次实例化对象的时候,均会帮我们自动执行构造函数里的代码。

在python中,使用_init_ 作为构造函数,如果不显式写构造函数,python会自动创建一个无任何操作的默认构造函数。

class Person:
    def __init__(self):
        print("person")

person1 = Person()
person2 = Person()

# 输出:person

作为模板,在构造函数中,为必须的属性绑定对应的值。

class Person:
    def __init__(self, name, age, height):
        self.name = name
        self.age = age
        self.height = height

    def introduce_self(self):
        print(self.name, self.age, self.height)

# 实例化对象的时候,为属性赋值
person = Person("lixiang", 11, 11)
# 调用对象方法可以使用对象名.方法名()
person.introduce_self()

# 输出:lixiang 11 11

注意:当使用了构造函数,且构造函数式带参的且无默认参数,此时,实例化对象的时候,必须显式入参,否则会报错。若要避免错误,可以在构造函数使用默认参数。

3.类变量与实例变量

类变量: 类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。类变量在整个实例化的对象中是公用的。

实例变量: 定义在方法中的变量,用 self 绑定到实例上,只作用于当前实例的类。

访问实例变量可以使用对象名.属性,访问类变量可以使用类名.属性。

class Person:

    # 类变量
    total = 0

    def __init__(self, name, age, height):
        # 实例变量
        self.name = name
        self.age = age
        self.height = height

person = Person("lixiang", 11, 12)
print(person.name)
# 如果要修改实例变量的值,可以使用对象名.属性=新值的方式进行赋值
person.name = "zhangsan"
print(person.name)
print(person.total)
# 如果要修改类变量的值,可以使用类名.属性=新值的方式进行赋值
Person.total = 1
print(person.total)

# 输出:
# lixiang
# zhangsan
# 0
# 1

实例变量查找规则:先从实例变量里面找,找不到,看看类变量有没有,没有的话,去父类找,还是找不到报错。

print(person.total)之所以没有报错,就是这个原因。

在对象里面,有一个__dict__对象,存储着对象相关的属性。

print(person.__dict__)

# 输出:{'name': 'zhangsan', 'age': 11, 'height': 12}
# 以字典的形式输出,输出对象的相关属性。

同样,类也有对应的__dict__,存储着与类相关的信息。

print(Person.__dict__)

# 输出:{'__module__': '__main__', 'total': 1, '__init__': <function Person.__init__ at 0x10e7bc4a0>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None}

除了__dict__,还有以下几个Python的内置属性。

  • _doc_ :类的文档字符串
  • _name_: 类名
  • _module_: 类定义所在的模块(类的全名是’main.className’,如果类位于一个导入模块mymod中,那么className.module 等于 mymod)
  • _bases_ : 类的所有父类构成元素(包含了一个由所有父类组成的元组)

4.实例方法与self关键字

实例方法: 与实例变量类似,属于实例化之后的对象,定义实例方法至少要有一个self入参,调用是不需要传,只能由实例对象调用。

self关键字: self指向实例本身,我们在实例方法中要访问实例变量,必须使用self.变量名的形式。

class Person:
    total = 0
    def __init__(self, name, age, height):
        self.name = name
        self.age = age
        self.height = height
    def info(self):
        print("hello,my name is %s,my age is %d and i'm %d height" % (self.name,self.age, self.height))

# 输出:hello,my name is lixiang,my age is 11 and i'm 12 height

注意:不能直接使用类名去访问实例方法。

5.类方法与静态方法

类方法: 类方法使用装饰器@classmethod。第一个参数必须是当前类对象,该参数名一般约定为“cls”(不是cls也没关系,但是,约定俗成的东西不建议变动),通过它来传递类的属性和方法(不能传实例的属性和方法)

其调用对象可以是实例对象和类。

class Person:
    total = 0
    @classmethod
    def print_detail(cls):
        cls.total = 1
        print(cls.total)
# 实例话对象的时候,使用类名,即可完成实例化
Person.print_detail()

# 输出:1 

静态方法: 使用装饰器@staticmethod。参数随意,没有“self”和“cls”参数,但是方法体中不能使用类或实例的任何属性和方法。

静态方法是类中的函数,不需要实例。静态方法主要是用来存放逻辑性的代码,逻辑上属于类,但是和类本身没有关系,也就是说在静态方法中,不会涉及到类中的属性和方法的操作。可以理解为,静态方法是个独立的、单纯的函数,它仅仅托管于某个类的名称空间中,便于使用和维护。

class Person:
    total = 0
    @staticmethod
    def print_detail():
        print("hello word")
Person.print_detail()

# 输出:hello word

6.变量方法访问限制

_foo_: 定义的是特殊方法,一般是系统定义名字 ,类似 _init_() 之类的。

_foo: 以单下划线开头的表示的是 protected 类型的变量,即保护类型只能允许其本身与子类进行访问,不能用于 from module import *。

__foo: 双下划线的表示的是私有类型(private)的变量, 只能是允许这个类本身进行访问了。

foo: 什么都不加表示公有类型(public)的变量。

class Person():
    # 构造函数,用于为成员变量赋初始值
    def __init__(self, name):
        # 属性私有化
        self.__name = name

    # 只能通过提供的set方法去进行设置值
    def set_name(self, name):
        self.name = name

    # 私有方法,只能在当前类中进行调用
    def __info(self):
        print("my name is %s" % self.name)

7.面向对象之继承

继承可以使得子类具有父类的属性和方法或者重新定义、追加属性和方法等。

Python中在定义类的时候,类名后有个括号,当括号里写着另外一个类的名字时,表示该类继承于另外一个类。

# 定义动物类
class Animal:

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

    def eat(self):
        print(self.name,":吃饭")
        
class Dog(Animal):
    # 子类可以有自己的属性与方法
    def  eat_bones(self):
        print(self.name,":吃骨头")

class Cat(Animal):
    pass

dog = Dog("狗")
dog.eat()
dog.eat_bones()

cat = Cat("猫")
cat.eat()

# 输出:
# 狗 :吃饭
# 狗 :吃骨头
# 猫 :吃饭

注意:子类具备父类所有的属性与功能,但是父类并不具备子类的属性与功能。

当子类有自己的构造方法时,将会覆盖父类的构造方法。

class Animal:
    def __init__(self):
        print("Animal")
# Dog继承animal
class Dog(Animal):
    def __init__(self):
        print("Dog")
dog = Dog()

# 输出:Dog

子类可以重写父类方法,重写之后,当子类对象调用该方法时,执行的是子类中的方法实现。

class Animal:
    def __init__(self):
        print("Animal")
    def eat(self):
        print("Animal is eating")
# Dog继承animal
class Dog(Animal):
    def eat(self):
        print("Dog is eating")
dog = Dog()
dog.eat()

# 输出:Dog is eating

注意: 当且仅当子类方法与父类同名,入参相同,才可称之为重写父类的方法。

8.super的作用及其用法

super() 函数是用于调用父类(超类)的一个方法。一般是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是如果使用多继承,会涉及到查找顺序(MRO)、重复调用等种种问题。

语法:super(类名,self)

在python3中,可以直接使用super()而无需任何参数来调用父类。

class Animal:
    def __init__(self, name):
        self.name = name
# Dog继承animal
class Dog(Animal):
    def __init__(self, name):
        super(Dog, self).__init__(name)
        print("Dog")
dog = Dog("Tom")
print(dog.__dict__)
print(dog.name)

# 输出:
# Dog
# {'name': 'Tom'}
# Tom

9.抽象方法与多态

抽象方法:在面向对象编程语言中抽象方法指一些只有方法声明,而没有具体方法体的方法。抽象方法一般存在于抽象类或接口中。抽象类的一个特点是它不能直接被实例化,子类要么是抽象类,要么,必须实现父类抽象类里定义的抽象方法。

在python3中可以通过使用abc模块轻松的定义抽象类。

from abc import ABCMeta, abstractmethod
# 定义抽象类时,使用metaclass=ABCMeta
class Animal(metaclass=ABCMeta):
    # 抽象方法加上@abstractmethod注解
    @abstractmethod
    def eat(self):
        pass
class Dog(Animal):
    def eat(self):
        print("dog is eating")
dog = Dog()
dog.eat()

注意:抽象类的子类必须实现抽象类中所定义的所有方法,否则,程序不能正确运行。会报 TypeError: Can't instantiate abstract class Dog with abstract methods run 这个错误。

多态:不同的 子类对象调用 相同的 父类方法,产生 不同的 执行结果,可以增加代码的外部 调用灵活度。

from abc import ABCMeta, abstractmethod
class Animal(metaclass=ABCMeta):
    @abstractmethod
    def eat(self):
        pass

    @abstractmethod
    def run(self):
        pass
    def activity(self):
        self.eat()
        self.run()

class Dog(Animal):
    def eat(self):
        print("Dog is eating")
    def run(self):
        print("dog is running")

class Cat(Animal):
    def eat(self):
        print("cat is eating")
    def run(self):
        print("cat is running")
# 不同的子类对象,调用父类的activity方法,产生不同的执行结果
dog = Dog()
cat = Cat()
dog.activity()
cat.activity()
# 输出:
# Dog is eating
# dog is running
# cat is eating
# cat is running 

10.Python多继承

Python多继承会拥有所有父类的方法。

class Father:
    def power(self):
        print("大力")

class Mother:
    def sing(self):
        print("唱歌")

class Me(Father, Mother):
    pass

me = Me()
me.power()
me.sing()

# 输出:
# 大力
# 唱歌

当继承多个父类时,如果父类中有相同的方法,那么子类会优先使用最先被继承的方法。

class Father:
    def eat(self):
        print("喜欢吃红烧猪排骨")

class Mother:
    def eat(self):
        print("喜欢吃咸菜小米粥")

class Me(Father, Mother):
    pass

me = Me()
me.eat()

# 输出:喜欢吃红烧猪排骨

11.Python枚举类

(1)什么是枚举

在数学和计算机科学理论中,一个集的枚举是列出某些有穷序列集的所有成员的程序,或者是一种特定类型对象的计数。这两种类型经常(但不总是)重叠。

定义枚举类继承Enum类。

from enum import Enum, unique
class Class(Enum):
    JAVA = 1
    PYTHON = 2
    GO = 3

def test(clazz):
    if clazz == Class.JAVA:
        print("JAVA")
    elif clazz == Class.PYTHON:
        print("PYTHON")
    else:
        print("GO")

test(Class.JAVA)

通过枚举成员获取key以及value。

# 通过枚举成员获取名字
print(Class.JAVA.name)
# 通过枚举成员获取值
print(Class.JAVA.value)

# 输出:
# JAVA
# 1

通过值获取枚举成员。

print(Class(1))

# 输出:JAVA

注意:定义枚举时,其枚举成员的名称不允许相同。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1438225.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java实现批量视频抽帧2.0

继上个版本 对其进行略微升级 &#x1f913; 上个版本仅对一个视频进行抽帧处理 此版本可对一个文件夹内的全部视频进行抽帧并对应的文件夹进行帧图片的保存 1️⃣配置pom.xml &#xff08;保持上次不变&#xff09; <dependencies><dependency><grou…

推理系统学习笔记

一些学习资料 最近对MLsys比较感兴趣&#xff0c;遂找些资料开始学习一下 https://fazzie-key.cool/2023/02/21/MLsys/https://qiankunli.github.io/2023/12/16/llm_inference.htmlhttps://dlsyscourse.orghttps://github.com/chenzomi12/DeepLearningSystem/tree/main/04Infe…

数智文旅:智慧文旅中的数字化转型

在数字化浪潮席卷全球的今天&#xff0c;旅游业作为传统服务业的代表&#xff0c;正面临着前所未有的转型压力与机遇。智慧文旅&#xff0c;作为旅游业与数字技术深度融合的产物&#xff0c;不仅标志着旅游业进入了全新的发展阶段&#xff0c;更预示着未来旅游业将朝着更加智能…

QAnything之BCEmbedding技术路线

QAnything和BCEmbedding简介 QAnything[github]是网易有道开源的检索增强生成式应用&#xff08;RAG&#xff09;项目&#xff0c;在有道许多商业产品实践中已经积累丰富的经验&#xff0c;比如有道速读和有道翻译。QAnything是一个支持任意格式文件或数据库的本地知识库问答系…

【开源】JAVA+Vue+SpringBoot实现公司货物订单管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 客户管理模块2.2 商品维护模块2.3 供应商管理模块2.4 订单管理模块 三、系统展示四、核心代码4.1 查询供应商信息4.2 新增商品信息4.3 查询客户信息4.4 新增订单信息4.5 添加跟进子订单 五、免责说明 一、摘要 1.1 项目…

Tauri 的基本使用笔记

文章目录 前言如何将 Tauri 集成到前端项目?进程间通信&#xff08;命令&#xff09;const invoke window.__TAURI__.invoke; 进程间通信&#xff08;事件&#xff09;前端 ⇒ RustRust ⇒ 前端我的疑问 开发时的一些技巧用代码打开前端的开发者工具让 Tauri 不要监听文件Rus…

Leetcode 30天高效刷数据结构和算法 Day1 两数之和 —— 无序数组

两数之和 —— 无序数组 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案里不能重复出现…

数据结构(C语言)代码实现(七)——一元多项式的表示与相加

目录 前言 参考资料格式 头文件LinkList.h LocateElem函数&#xff0c;定位查找 有序插入&#xff08;没测试&#xff09; 完整代码 头文件polynomial.h 测试函数&#xff08;主函数&#xff09; 测试结果 前言 寒假在家&#xff0c;有点学不下去&#xff0c;写文章的…

java中ArrayList类常用API

前言&#xff1a;在学习java的ArrayList类的时候&#xff0c;有很多的API需要了解&#xff0c;下面我将举出其中在新手学习时使用频率较大的几个API。 先大体看一下有哪几个&#xff1a;&#xff08;如图&#xff09; 目录 1.add&#xff08;&#xff09; 解释&#xff1a; …

CSS太极动态图

CSS太极动态图 1. 案例效果 我们今天学习用HTML和CSS实现动态的太极&#xff0c;看一下效果。 2. 分析思路 太极图是由两个旋转的圆组成&#xff0c;一个是黑圆&#xff0c;一个是白圆。实现现原理是使用CSS的动画和渐变背景属性。 首先&#xff0c;为所有元素设置默认值为0…

非精线搜索步长规则Armijo规则Goldstein规则Wolfe规则

文章目录 非精确线搜索步长规则Armijo规则Goldstein规则Wolfe规则C示例代码参考链接 非精确线搜索步长规则 在数值优化中&#xff0c;线搜索是一种寻找合适步长的策略&#xff0c;以确保在目标函数上获得足够的下降。如最速下降法&#xff0c;拟牛顿法这些常用的优化算法等&am…

异步解耦之RabbitMQ(三)_RabbitMQ队列

异步解耦之RabbitMQ(一) 异步解耦之RabbitMQ(二)_RabbitMQ架构及交换机 RabbitMQ提供了许多功能和选项&#xff0c;包括队列和消息的 TTL&#xff08;Time-To-Live&#xff0c;生存时间&#xff09;。在本篇博客中&#xff0c;我们将深入探讨 RabbitMQ 队列和消息的 TTL&…

Laykefu客服系统 任意文件上传

【产品介绍】 Laykefu 是一款基于workermangatawayworkerthinkphp5搭建的全功能webim客服系统&#xff0c;旨在帮助企业有效管理和提供优质的客户服务 【漏洞介绍】 Laykefu客服系统/admin/users/upavatar.html接口处存在文件上传漏洞 【资产测绘Query】 fofa语法&#xf…

IS-IS weight影响路由加表

拓扑图 配置 nexthop weight影响路由加入路由表 weight默认为255&#xff0c;取值1~255&#xff0c;值越小越优先 sysname R1 # isis 1is-level level-1cost-style widenetwork-entity 49.1234.0000.0000.0001.00log-peer-change topology # interface GigabitEthernet0/0/0…

freeRTOS总结(十四)任务通知

1、任务通知 任务通知&#xff1a; 用来通知任务的&#xff0c;任务控制块中的结构体成员变量ulNotifiedValue就是这个通知值 使用队列、信号量、事件标志组时都需另外创建一个结构体&#xff0c;通过中间的结构体进行间接通信&#xff01; 使用任务通知时&#xff0c;任务结…

C#上位机与三菱PLC的通信02--MC协议介绍

1、协议介绍 三菱 PLC MC 协议是一种用于三菱 PLC 与上位机之间进行数据通信的协议&#xff0c;也称为 Mitsubishi Communication Protocol。该协议支持串口、以太网等多种通讯方式&#xff0c;可实现实时数据的采集和交换。三菱PLC的MC协议是一种数据通信协议&#xff0c;它用…

跟着pink老师前端入门教程-day21

5.4 常见flex布局思路 5.5 背景线性渐变 语法&#xff1a; background: linear-gradient( 起始方向 , 颜色 1, 颜色 2, ...); background: -webkit-linear-gradient(left, red , blue); background: -webkit-linear-gradient(left top, red , blue); 背景渐变必须添加浏览…

【Mybatis】从0学习Mybatis(1)

前言 本篇文章是从0学习Mybatis的第一篇文章&#xff0c;由于篇幅太长CSDN会限流&#xff0c;因此我打算分开三期来写&#xff0c;这是第一期&#xff01; 1.怎么理解MyBatis是一个框架&#xff1f; 温馨提示&#xff1a;接下来的你不一定能看懂&#xff01; MyBatis是一个J…

1Panel面板如何安装并结合内网穿透实现远程访问本地管理界面

文章目录 前言1. Linux 安装1Panel2. 安装cpolar内网穿透3. 配置1Panel公网访问地址4. 公网远程访问1Panel管理界面5. 固定1Panel公网地址 前言 1Panel 是一个现代化、开源的 Linux 服务器运维管理面板。高效管理,通过 Web 端轻松管理 Linux 服务器&#xff0c;包括主机监控、…

照片去除水印的方法有哪些?这些方法快收藏保存起来

当你踏破铁鞋无觅处&#xff0c;在茫茫网海中寻得心仪的头像或壁纸美图&#xff0c;却发现那完美的画面上赫然带着平台水印&#xff0c;是不是感觉如鲠在喉&#xff1f;但又不知道照片去除水印的方法有哪些而束手无策&#xff1f;别担心&#xff0c;今天我就为你带来几招去水印…