Python之面向对象和类

一.类

1.类的定义:

                class 类名:

                       “”“注释 ”“”

                        pass

2.实例的创建:

实例 = 类名(parameterlist)
parameterlist:定义类时__init__()方法的参数,如果该方法只有一个self参数,parameterlist可以省略

class Goose():"""定义了鹅类"""passgoose =  Goose()
print(goose)#<__main__.Goose object at 0x00000229213C6900>

3.创建类的构造函数方法:__init__()方法

        定义类时,通常会包含一个__init__()方法。该方法是构造函数方法,每当创建一个类的新实例时,Python都会自动执行它。
1.__init__()方法用来初始化新创建对象,在一个对象被创建以后会立即调用。
2. __init__()方法必须包含一个self参数并且必须是第一个参数self参数是一个指向实例本身的引用,用于访问类中的属性和方法。(相当于JAVA中的this)

       3.当__init__()方法只有一个参数时,在创建类的实例时,不需要指定实际参数。
4.__init__()方法的名称是以两个连续下划线开头和结尾,这是一种约定,用于区分Python默认方法和普通方法。

        5._init_()方法可以分为无参构造方法和有参构造方法。当使用无参构造方法创建对象时,所有对象的属性都有相同的初始值;当使用有参构造为法创建对象时,对象的属性可以有不同的初始值;

        6.如果你写多个构造方法,但是你在调用的时候,后写的构造方法会取代前面的构造方法(无论这两者参数上是否有区别),这点与JAVA不一样,所以一般一个类只有一个构造方法。

        7.一般来说,构造方法里面写初始化内容

class Goose():def __init__(self):print ("self:",self) #self: <__main__.Goose object at 0x0000022CD8766900>print("type of self:",type(self))#type of self: <class '__main__.Goose'>print("我是鹅类,我会自动执行该语句")           
g=Goose()

在__init__()方法中,除了self参数外,还可以自定义一些参数,参数间使用逗号“,”进行分隔。

class Goose:'''鹅类'''def __init__(self,beak,wing,claw):print("我是鹅类!我有以下特征:")print(beak)print(wing)print(claw)
beak_1 = "喙的基部较高,长度和头部的长度几乎相等"
wing_1 = "翅膀长而尖"
claw_1 = "爪子是蹼壮的"
wildGoose = Goose(beak_1,wing_1,claw_1)

当然,也可以不用构造函数(一般不推荐这样)

class Rect1():def getPeri(self,a,b):print("周长为:",(a+b)*2)def getArea(self,a,b):print("面积为:",a*b)
r1=Rect1()
r1.getPeri(3,4)
r1.getArea(3,4)
print(r1.__dict__)class Rect2():def __init__(self,a,b):self.a=aself.b=bdef getPeri(self):print("周长为:",(self.a+self.b)*2)def getArea(self):print("面积为:",self.a*self.b)
r2=Rect2(5,6)
r2.getPeri()
r2.getArea()
print(r2.__dict__)

二.类的成员

1.类的成员,静态定义

定义属性并访问
数据成员是指在类中定义的变量,即属性,根据定义位置,又可以分为类属性和实例属性。
① 类属性
类属性是指定义在类中,并且在函数体外的属性。
类属性可以在类的所有实例之间共享值,也就是在所有实例化的对象中公用。
类属性可以通过类名称或者实例名访问。

class Goose:'''鹅类'''neck = "脖子较长"wing = "振翅频率高"leg = "腿位于身体的中心支点,行走自如"def __init__(self):print("我属于鹅类!我有以下特征:")print(self.neck)print(self.wing)print(self.leg)
geese = Goose()

2.动态添加属性

在Python中除了可以通过类名称访问类属性,还可以动态地为类和对象添加属性

class Goose:'''鹅类'''neck = "脖子较长"wing = "振翅频率高"leg = "腿位于身体的中心支点,行走自如"def __init__(self):print("我属于鹅类!我有以下特征:")print(Goose.neck)print(Goose.wing)print(Goose.leg)geese = Goose()
#在类外,动态的为对象添加属性
geese.beak = "喙的基部较高,长度和头部的长度几乎相等"
print("鹅的喙:",geese.beak)

3.实例属性


实例属性,在JAVA中类似于对象的属性(官方不是这个叫法),实例属性是指在类的方法中的属性,就是__init__()构造方法中的参数,只作用于当前实例中。

class Goose:'''鹅类'''neck = "脖子较长"wing = "振翅频率高"leg = "腿位于身体的中心支点,行走自如"def __init__(self,name):self.name = nameprint("我属于鹅类!我有以下特征:")print(self.neck)print(self.wing)print(self.leg)print("实例属性,geese特有:",name)geese = Goose("娃哈哈")

4.实例属性和类属性的区别

class Dog:# 类属性(所有狗共享)species = "Canis familiaris"def __init__(self, name):# 实例属性(每个狗独立)self.name = name# 创建两个实例
dog1 = Dog("Buddy")
dog2 = Dog("Max")# 访问类属性(通过类名或实例名)
print(Dog.species)          # 输出: Canis familiaris
print(dog1.species)         # 输出: Canis familiaris# 访问实例属性(只能通过实例名)
print(dog1.name)            # 输出: Buddy
print(dog2.name)            # 输出: Max# 尝试通过类名访问实例属性(报错!)
#print(Dog.name)             # AttributeError: type object 'Dog' has no attribute 'name'# 修改类属性
Dog.species = "Canis lupus"
print(dog1.species)         # 输出: Canis lupus(所有实例同步更新)
print(dog2.species)         # 输出: Canis lupus# 通过实例修改"类属性"(实际是创建同名实例属性)
dog1.species = "Golden Retriever"
print(dog1.species)         # 输出: Golden Retriever(仅影响dog1)
print(dog2.species)         # 输出: Canis lupus(dog2不受影响)# 类属性本身未被修改
print(Dog.species)          # 输出: Canis lupus

总结如下:

特性类属性实例属性
定义位置类内部,__init__ 方法之外通常在 __init__ 方法内
归属属于类属于实例
访问方式类名或实例名均可访问只能通过实例名访问
共享性所有实例共享每个实例独立
修改影响修改后影响所有实例修改仅影响当前实例

5.访问限制

        为了保证类内部的某些属性或方法不被外部所访问,可以在属性或方法名前面添加单下划线(_foo)、双下划线(__foo)或首尾加双下划线(__foo__),从而限制访问权限。
其中,单下划线、双下划线、首尾双下划线的作用如下:
首尾双下划线表示定义特殊方法,一般是系统定义名字,如__init__(),一般自定义不推荐这种定义
以单下划线开头的表示protected(保护)类型的成员,只允许类本身和子类进行访问,但
不能使用“from module import *”语句导入
双下划线表示private(私有)类型的成员,只允许定义该方法的类本身进行访问,而且也
不能通过类的实例进行访问
,但是可以通过“类的实例名._类名_xxx”方式访问。

class MyClass:def __init__(self):self.public_value = "Public"       # 公开属性,可任意访问self._protected_value = "Protected"  # 保护属性(单下划线开头)self.__private_value = "Private"    # 私有属性(双下划线开头)def public_method(self):print("This is a public method.")def _protected_method(self):print("This is a protected method.")def __private_method(self):print("This is a private method.")def __special_method__(self):print("This is a special method (magic method).")class SubClass(MyClass):"""继承MyClass类"""def show_protected(self):print("接受保护属性 :", self._protected_value)def try_private(self):# 直接访问私有属性会报错# print(self.__private_var)  # 报错:AttributeError# 但可以通过 _类名__私有属性 的方式访问print("Accessing private from subclass:", self._MyClass__private_var)# 实例化
obj = MyClass()
sub_obj = SubClass()# 1. 公开成员(无下划线)
print(obj.public_value)            # 输出: Public
obj.public_method()              # 输出: This is a public method.# 2. 保护成员(单下划线开头)
print(obj._protected_value)        # 输出: Protected(可以访问但不推荐)
obj._protected_method()          # 输出: This is a protected method.
sub_obj.show_protected()         # 输出: Accessing protected from subclass: Protected# 3. 私有成员(双下划线开头)
# print(obj.__private_var)       # 报错:AttributeError
# obj.__private_method()         # 报错:AttributeError
print(obj._MyClass__private_var) # 输出: Private(通过名称重整访问)
obj._MyClass__private_method()   # 输出: This is a private method.
sub_obj.try_private()            # 输出: Accessing private from subclass: Private# 4. 特殊方法(首尾双下划线)
obj.__special_method__()         # 输出: This is a special method (magic method).

三.类的方法

1.实例方法

        实例方法是指在类中定义的函数。该函数是一种在类的实例上操作的函数。同__init__()方法一样,实例方法的第一个参数必须是self,并且必须包含一个self参数.

语法:

def 方法名(self,参数1,参数2....):
方法内容

调用形式:

        只能通过类名.方法名(参数)

class Goose:def __init__(self,beak,wing,claw):print("我是鹅类!我有以下特征:")print(beak)print(wing)print(claw)def fly(self,state):print(state)
'''*******************调用方法**********************'''
beak_1 = "喙的基部较高,长度和头部的长度几乎相等"
wing_1 = "翅膀长而尖"
claw_1 = "爪子是蹼壮的"
wildGoose = Goose(beak_1,wing_1,claw_1)
wildGoose.fly("我飞行的时候,一会排成个人字,一会排成个一字")

2.类方法:

在该方法前面必须加上@classmethod(注解,装饰器),来表明这是一个类方法,且必须带一个参数cls(跟类方法的self一样,但是为了区分两者,这里要写作cls)

调用方式:

        推荐     类名.方法名调用,

        不推荐   对象名.方法名

作用

  • 用于操作类属性(而不是实例属性)

  • 常用于工厂方法(创建类的不同实例)。

class Dog:"""species为一个类属性@classmethod后的类方法一般为了操作类属型(调用修改等等)"""species = "Canine"  # 类属性def __init__(self, name):self.name = name@classmethoddef get_species(cls):return cls.species  # 访问类属性@classmethoddef from_birth_year(cls, name, birth_year):age = 2025 - birth_yearreturn cls(name)  # 返回一个新的 Dog 实例,并将name传给新的实例(毕竟建造一个实例需要参数)# 通过类名调用类方法
print(Dog.get_species())  # 输出: Canine# 类方法作为工厂方法创建实例
dog = Dog.from_birth_year("Max", 2018)
print(dog.name)  # 输出: Max

注意:return cls(name)意味着

# 返回一个新的 Dog 实例,并将name传给新的实例(毕竟建造一个实例需要参数)

3..静态方法

在该方法前面必须加上@staticmethod(注解),来表明这是一个静态方法,可以无参数,

调用方式:

        推荐     类名.方法名调用,

        不推荐   对象名.方法名

  • 作用

    • 与类相关,但不依赖类或实例的状态(即不访问 self 或 cls)。

    • 类似于普通函数,但逻辑上属于类。

class MathUtils:@staticmethoddef add(a, b):return a + b@staticmethoddef multiply(a, b):return a * b# 通过类名调用静态方法
print(MathUtils.add(3, 7))  # 输出: 10# 也可以实例化后调用(但不推荐,静态方法不依赖实例)
utils = MathUtils()
print(utils.multiply(2, 4))  # 输出: 8

4.特殊方法:

(1)析构方法__del__()


Python中的垃圾回收主要采用的是引用计数。引用计数是一种内存管理技术,它通过引用计数器记录所有对象的引用数量,当对象的引用计数器数值为0时,就会将该对象视为垃圾进行回收

        getrefcount()函数是 sys模块中用于统计对象引用数量的函数,其返回结果通常比预期的结果大1。这是因为getrefcount()函数也会统计临时对象的引用。当一个对象的引用计数器数值为0时,就会调用_del__()方法,这个方法就是类的析构方法。系统就会销毁这个对象,收回对象所占用的内存空间。
所以析构方法(即__del_()方法)是用于销毁对象时系统自动调用的方法。每个类中也都默认有一个__del__()目方法,可以显式地定义析构方法。
        注意:析构方法不是销毁方法,而是在销毁之前释放资源,销毁方法是靠py底层代码来完成

(2)__str__()

简单来说就是相当于JAVA中的toString方法

若是不重写,就会用py自带的方法

class Person:def __init__(self, name, age):self.name = nameself.age = agep = Person("Alice", 25)
print(p)  # 输出: <__main__.Person object at 0x7f8b1c1b3d90>

若是重写:

class Person:def __init__(self, name, age):self.name = nameself.age = agedef __str__(self):return f"Person(name={self.name}, age={self.age})"p = Person("Alice", 25)
print(p)  # 输出: Person(name=Alice, age=25)

四.继承:

跟Java一样有object类为总的父类

1.单继承

基本语法:

        class 子类名(父类名)

# 父类
class Animal:def speak(self):print("动物发出声音")def eat(self):print("父类动物在吃东西")# 子类
class Dog(Animal):  # Dog继承Animaldef speak(self):  # 重写父类方法print("汪汪汪!")# 使用
animal = Animal()
animal.speak()  # 输出:动物发出声音dog = Dog()
dog.speak()     # 输出:汪汪汪!
dog.eat()       #子类继承父类方法eat

        

super关键字编程super方法,用法相同

2.多继承

1.在职研究生继承了Student和staff类

2.两者都有showinfo方法,调用对象.方法名,会优先调用第一个继承的父类 的方法,这里即Student类的showinfo方法

  • 若想调用Teacher的方法,可以:

    1. 调整继承顺序:class Person(Teacher, Student)

    2. 直接指定:Teacher.showinfo(p)

    3. 在子类中重写方法并手动选择调用哪个父类的方法是

3. 方法重写(Override)

子类可以重写父类的方法以改变其行为

# 父类
class Animal:def speak(self):print("动物发出声音")def eat(self):print("父类动物在吃东西")# 子类
class Dog(Animal):  # Dog继承Animaldef speak(self):  # 重写父类方法print("汪汪汪!")# 使用
animal = Animal()
animal.speak()  # 输出:动物发出声音dog = Dog()
dog.speak()     # 输出:汪汪汪!

4. super()函数

# 父类
class Animal:def speak(self):print("动物发出声音")def eat(self):print("父类动物在吃东西")# 子类
class Dog(Animal):  # Dog继承Animaldef speak(self):  # 重写父类方法print("汪汪汪!")super().eat()# 使用
dog = Dog()
dog.speak()     # 输出:汪汪汪!

5.强制转换

        对于Python继承机制

class Animal:def eat(self):print("动物吃东西")class Dog(Animal):  # Dog继承自Animaldef eat(self):print("狗吃骨头")def bark(self):print("汪汪叫")class Cat(Animal):def eat(self):print("猫吃鱼")
# 向上转型(自动) - 子类转父类
animal = Dog()  # 狗是动物(自动转换)
animal.eat()    # 输出: 狗吃骨头def trans(animal,obj):if isinstance(animal, obj):dog = animal  dog.bark()    else:print("不能将动物转为动物子类")trans(animal,Dog)
"""狗吃骨头
汪汪叫
"""
dog = Dog()
cat = Cat()
trans(cat,Dog)#不能将动物转为动物子类

        动物= 狗可以,动物=猫 可以,但是不能   狗=  动物

        要想狗 = 动物必须强制转换,狗 = (狗)动物

class Animal:def __init__(self, name):self.name = nameclass Dog:def __init__(self, animal):  # 构造函数中实现转换self.name = animal.namedef bark(self):print(f"{self.name}在汪汪叫")animal = Animal("旺财")
dog = Dog(animal)  # 强制将Animal转为Dog
dog.bark()         # 输出: 旺财在汪汪叫

五.多态

首先Python中的多态根JAVA不一样,JAVA的多态必须要在继承的基础之上,但是py的多态,根本不关心你是不是继承,是不是相同的数据类型。只要不同的类中有相同的方法,即可实现多态。

所以要定义一个接口,实现类的多态化。

class Animal:def eat(self):print("人吃五谷杂粮")class Dog:def eat(self):print("狗吃骨头")class Cat:    def eat(self):print("猫吃鱼")def jiekou(obj):obj.eat()# 创建实例
animal = Animal()
dog = Dog()
cat = Cat()# 多态调用
jiekou(animal)  # 输出: 人吃五谷杂粮
jiekou(dog)     # 输出: 狗吃骨头
jiekou(cat)     # 输出: 猫吃鱼

 

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

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

相关文章

【力扣 困难 C】329. 矩阵中的最长递增路径

目录 题目 解法一 题目 待添加 解法一 int max(int a, int b) {return a > b ? a : b; }int search(int** matrix, int m, int n, int i, int j, int (*dp)[n]) {if (dp[i][j]) {return dp[i][j];}int len 0;if (i > 0 && matrix[i - 1][j] > matrix[i]…

Blueprints - UE5的增强输入系统

一些学习笔记归档&#xff1b;增强输入系统由两部分组成&#xff1a;Input Action和Input Mapping ContextInput Action是输入操作的映射&#xff08;操作中比如有移动、跳跃等&#xff09;&#xff0c;Input Mapping Context是输入情境的映射&#xff08;对各种操作的具体按键…

Python 【技术面试题和HR面试题】➕ 动态类型、运算符、输入处理及算法编程问答

1.技术面试题 &#xff08;1&#xff09;TCP与UDP的区别是什么&#xff1f; 答&#xff1a; ①连接性&#xff1a;TCP 面向连接&#xff0c;3次握手及4次挥手&#xff0c;建立端到端的虚链路像&#xff1b;UDP 无连接&#xff0c;直接发送&#xff0c;无需预先建立连接 。 ②传…

etcd-cpp-apiv3 二次封装

接口介绍头文件#include <etcd/Client.hpp> #include <etcd/KeepAlive.hpp> #include <etcd/Response.hpp> #include <etcd/SyncClient.hpp> #include <etcd/Value.hpp> #include <etcd/Watcher.hpp>下面从功能介绍几个类的概念Value &…

【网络与系统安全】强制访问控制——Biba模型

一、模型定义与目标 提出背景&#xff1a;1977年由Ken Biba提出&#xff0c;是首个完整性安全模型&#xff0c;与BLP模型形成对偶&#xff08;BLP关注机密性&#xff0c;Biba关注完整性&#xff09;。核心目标&#xff1a;防止低完整性信息污染高完整性信息&#xff0c;避免未授…

从架构抽象到表达范式:如何正确理解系统架构中的 4C 模型20250704

&#x1f9e9; 从架构抽象到表达范式&#xff1a;如何正确理解系统架构中的 4C 模型&#xff1f; “4C”到底是架构的组成结构&#xff0c;还是架构图的表现方式&#xff1f;这类看似细节的问题&#xff0c;其实直击了我们在系统设计中认知、表达与落地之间的张力。 &#x1f5…

Debian10安装Mysql5.7.44 笔记250707

Debian10安装Mysql5.7.44 笔记250707 1️⃣ 参考 1 在Debian 10 (Buster) 上安装 MySQL 5.7.44 的步骤如下&#xff1a; 1. 添加 MySQL APT 仓库 MySQL 官方提供了包含特定版本的仓库&#xff1a; # 下载仓库配置包 wget https://dev.mysql.com/get/mysql-apt-config_0.8.28…

20250706-6-Docker 快速入门(上)-镜像是什么?_笔记

一、镜像是什么&#xfeff;1. 一个分层存储的文件&#xff0c;不是一个单一的文件分层结构: 与传统ISO文件不同&#xff0c;Docker镜像由多个文件组成&#xff0c;采用分层存储机制存储优势: 每层可独立复用&#xff0c;显著减少磁盘空间占用&#xff0c;例如基础层可被多个镜…

[SystemVerilog] Clocking

SystemVerilog Clocking用法详解 SystemVerilog 的 clocking 块&#xff08;Clocking Block&#xff09;是一种专门用于定义信号时序行为的构造&#xff0c;主要用于验证环境&#xff08;如 UVM&#xff09;中&#xff0c;以精确控制信号的采样和驱动时序。clocking 块通过将信…

kong网关基于header分流灰度发布

kong网关基于header分流灰度发布 在现代微服务架构中&#xff0c;灰度发布&#xff08;Canary Release&#xff09;已经成为一种常用且安全的上线策略。它允许我们将新版本的功能仅暴露给一小部分用户&#xff0c;从而在保证系统稳定性的同时收集反馈、验证效果、规避风险。而作…

Go语言gin框架原理

在gin框架中&#xff0c;最关键的就是前缀树&#xff0c;是很重要的。gin框架本质上是在http包的基础之上&#xff0c;对其的一个二次封装。这里借鉴一下小徐先生的图&#xff0c;可能当前版本的gin可能内容有所改变&#xff0c;但大致思想还是这样。gin框架所做的就是提供一个…

4、Sending Messages

本节介绍如何发送消息。Using KafkaTemplate本节介绍如何使用KafkaTemplate发送消息。OverviewKafkaTemplate封装了一个生产者&#xff0c;并提供了向Kafka主题发送数据的便利方法。以下列表显示了KafkaTemplate的相关方法&#xff1a;CompletableFuture<SendResult<K, V…

CSS长度单位问题

在 CSS 中&#xff0c;100px 的逻辑长度在不同分辨率的手机屏幕上是否表现一致&#xff0c;取决于 设备的像素密度&#xff08;devicePixelRatio&#xff09; 和 视口&#xff08;viewport&#xff09;的缩放设置。以下是详细分析&#xff1a;1. 核心概念 CSS 像素&#xff08;…

基于Java+SpringBoot的图书管理系统

源码编号&#xff1a;S606源码名称&#xff1a;基于SpringBoot的图书管理系统用户类型&#xff1a;双角色&#xff0c;用户、管理员数据库表数量&#xff1a;12 张表主要技术&#xff1a;Java、Vue、ElementUl 、SpringBoot、Maven运行环境&#xff1a;Windows/Mac、JDK1.8及以…

XTOM工业级蓝光三维扫描仪用于笔记本电脑背板模具全尺寸检测

镁合金具有密度小、强度高、耐腐蚀性好等优点&#xff0c;成为笔记本电脑外壳主流材料。冲压模具作为批量生产笔记本电脑镁合金背板的核心工具&#xff0c;其精度直接决定了产品的尺寸一致性、结构可靠性与外观品质。微米级模具误差可能在冲压过程中被放大至毫米级&#xff08;…

运维打铁: MongoDB 数据库集群搭建与管理

文章目录思维导图一、集群基础概念1. 分片集群2. 副本集二、集群搭建1. 环境准备2. 配置副本集步骤 1&#xff1a;修改配置文件步骤 2&#xff1a;启动 MongoDB 服务步骤 3&#xff1a;初始化副本集3. 配置分片集群步骤 1&#xff1a;配置配置服务器副本集步骤 2&#xff1a;启…

HCIP-Datacom Core Technology V1.0_5 OSPF特殊区域及其他特性

在前面的章节中&#xff0c;OSPF可以划分区域&#xff0c;减轻单区域里面LSDB的规模&#xff0c;从而减轻路由器的负荷&#xff0c;虽然OSPF能够划分区域&#xff0c;但是依旧需要维护域间路由和外部路由&#xff0c;这样随着网络规模的不断扩大&#xff0c;路由器所维护的LSDB…

实时开发IDE部署指南

&#x1f525;&#x1f525; AllData大数据产品是可定义数据中台&#xff0c;以数据平台为底座&#xff0c;以数据中台为桥梁&#xff0c;以机器学习平台为中层框架&#xff0c;以大模型应用为上游产品&#xff0c;提供全链路数字化解决方案。 ✨杭州奥零数据科技官网&#xff…

深入解析 RAGFlow:文件上传到知识库的完整流程

在 RAGFlow 这样的检索增强生成&#xff08;RAG&#xff09;系统中&#xff0c;知识库是其核心。用户上传的文档如何高效、可靠地转化为可检索的知识&#xff0c;是系统稳定运行的关键。今天&#xff0c;我们就来深入探讨 RAGFlow 中文件上传到知识库的完整流程&#xff0c;揭秘…

cad_recognition 笔记

Hubch/cad_recognition | DeepWiki https://github.com/Hubch/cad_recognition winget install python.python.3.10 python -m venv venv micromamba activate ./venv pip install paddleocr2.9.0 pip install poetry pip install moviepy1.0.3 下次要用conda建环境 或者…