一文让你学会python:面向对象

news2024/9/23 17:11:09

面向对象编程(OOP)

一.类与实例

1.类:

是对现实世界描述的一种类型,是抽象的,是实例的模板,类名采用大驼峰,定义方式为 `class 类名: pass 。

2.实例

根据类创建的具体对象,通过类名加括号(类名())创建。实例是具体的,内容依赖于类

3.self

在类的方法中,self 代表调用该方法的实例本身,在类内来代表未来的实例。通过 self 可以访问实例的属性和其他方法。

二.初始化函数 __init__

这是类的特殊方法,通过初始化 self 来初始化未来的实例,向 self 中添加数据就是向实例中添加数据。

运行结果:

三.魔法函数(特殊方法)

这些方法允许对象进行特定的操作,如字符串表示(__str__)、长度计算(__len__)、比较(__eq____ne__ 等)和算术运算(__add____sub__ 等)。


class MyClass:
    def __init__(self, name, age):
        print(f"初始化函数执行了")
        self.name = name
        self.age = age

    def __str__(self):
        return f"醒醒了:{self.name}"

    def __len__(self):
        return len(self.name)

    def __eq__(self, other):
        return self.age == other.age

    def __ne__(self, other):
        return self.age != other.age

    def __gt__(self, other):
        return self.age > other.age

    def __ge__(self, other):
        return self.age >= other.age

    def __lt__(self, other):
        return self.age < other.age

    def __le__(self, other):
        return self.age <= other.age

    def __add__(self, other):
        return self.age + other.age

    def __sub__(self, other):
        return self.age - other.age

    def __mul__(self, other):
        return self.age * other.age

    def __divmod__(self, other):
        return divmod(self.age, other.age)

    def __mod__(self, other):
        return self.age % other.age

    def __truediv__(self, other):
        return self.age / other.age

    def __floordiv__(self, other):
        return self.age // other.age


mc = MyClass("张飞", 18)
print(mc)
print(len(mc))

mc2 = MyClass("孙尚香", 18)
print(mc == mc2, mc != mc2, mc > mc2, mc >= mc2, mc < mc2, mc <= mc2)

print(mc + mc2, mc - mc2, mc * mc2, mc % mc2, divmod(mc, mc2), mc / mc2, mc // mc2)

运行结果:

四.构造函数与析构函数

  • 构造函数:用于创建实例(`self`)并返回实例,可通过父类来创建实例super().__new__() 。
  • 析构函数__del__ 方法在对象被销毁时调用,用于执行清理工作。实例不再使用,销毁之前执行。

运行结果:

五.三大特性

封装

包括数据(如名字、年纪)及数据相关的操作(如获取名字、设置名字、获取年纪、设置年纪)。

"""
Light:  灯
数据 state
操作 is_open change_state
"""


class Light:
    def __init__(self):
        self.state = False  # 初始灯的状态为关闭
        self.colors = ["红色", "绿色", "蓝色"]  # 定义了三种颜色:红色、绿色、蓝色
        self.current = 0  # 初始颜色索引为0,即红色

    def is_open(self):
        return self.state  # 返回当前灯的状态,True 表示开启,False 表示关闭

    def change_state(self):
        self.state = not self.state  # 切换灯的状态,如果是开启就关闭,如果是关闭就开启

    def get_color(self):
        return self.colors[self.current]  # 返回当前灯的颜色

    def set_color(self):
        self.current += 1  # 切换到下一个颜色
        if self.current == len(self.colors):  # 如果颜色索引超过了颜色列表长度
            self.current = 0  # 则重新回到第一个颜色


# 示例用法
l0 = Light()
# 初始状态
print(l0.is_open())  # 输出: False,灯是关闭的
print("======================")
# 切换状态
l0.change_state()
print(l0.is_open())  # 输出: True,灯现在是开启的
print("======================")
# 再次切换状态
l0.change_state()
print(l0.is_open())  # 输出: False,灯又关闭了
print(l0.get_color())  # 输出: 红色,因为当前颜色索引是0
print("======================")
# 切换颜色
l0.set_color()
print(l0.get_color())  # 输出: 绿色,因为当前颜色索引现在是1
print("======================")
l0.set_color()
print(l0.get_color())  # 输出: 蓝色,因为当前颜色索引现在是2
print("======================")
l0.set_color()
print(l0.get_color())  # 输出: 红色,因为当前颜色索引超过了列表长度,重新回到0
print("======================")
l0.set_color()
print(l0.get_color())  # 输出: 绿色,依次循环显示颜色


运行结果:

继承

子类拥有父类的数据以及操作,子类不需要重新编写。Python 支持多继承,而 Java、C# 只支持单继承,通过接口等来实现多继承的功能。

多继承:

class MoveAble:
    def __init__(self, speed):
        self.speed = speed

    def move(self):
        print(f"I can move, my speed is {self.speed}m/s")

    def __str__(self):
        return "我是移动类"


class SpeakAble:
    def __init__(self, language):
        self.language = language

    def speak(self):
        print(f"I can speak {self.language}")

    def __str__(self):
        return "我是说话类"


class AttackAble:
    def __init__(self, skill):
        self.skill = skill

    def attack(self):
        print(f"使用{self.skill}发起攻击")

    def __str__(self):
        return "我是攻击类"


class Person(MoveAble, SpeakAble):
    def __init__(self, name, speed, language):
        # super().__init__()  会执行第一个父类
        # super().__init__(speed)

        # 通过类名表名 需要初始化哪个父类  必须传入self
        MoveAble.__init__(self, speed)
        SpeakAble.__init__(self, language)

        self.name = name

    def show(self):
        print(f"my name is {self.name}")

    def __str__(self):
        return "我是人类"


p0 = Person("小张", 50, "汉语")
p0.show()
p0.move()
p0.speak()

多态

Python 中可以理解到处都是多态,有两种形式,一是函数同名不同参数,通过 `*args` 实现;二是父子类多态,函数名参数都相同,但实现不同。

运行结果:

六.抽象类
  • 是特殊的类,内部可编写抽象方法,不能直接实例化,也可编写普通实例方法。子类继承抽象类必须实现抽象类的抽象方法
"""
抽象类:不直接实例化, 通过子类来产生实例
"""
from abc import ABC, abstractmethod


class Animal(ABC):
    """
    抽象类:拥有抽象方法 不能直接实例化
    通过装饰器abstractmethod把 walk 变为抽象方法
    """
    @abstractmethod
    def walk(self):
        pass

    def eat(self):
        print(f"可以吃")


# a0 = Animal()
# print(a0, isinstance(a0, Animal))

class Dog(Animal):
    """
    抽象类子类: 必须实现抽象类中的抽象方法
    """
    def walk(self):
        print(f"摇摇尾巴")


dog = Dog()
dog.eat()   # 调用继承自 Animal 的 eat() 方法
print(isinstance(dog, Dog), isinstance(dog, Animal))  # 检查实例的类型


class Cat(Animal):
    def walk(self):
        print(f"跳来跳去")


cat = Cat()
cat.eat()   # 调用继承自 Animal 的 eat() 方法
print(isinstance(cat, Cat), isinstance(cat, Animal))  # 检查实例的类型
七.类中内容
  • 实例属性:向实例中添加的数据,类内通过 self,类外通过实例。
  • 实例方法:第一个形参是 self,类内通过 self,类外通过实例
  • 类属性:向类中添加数据,获取与设置直接通过类名,通过实例获取不推荐,实例不能设置类属性。
  • 类方法:第一个形参一般是 cls,带有装饰器 classmethod,目的是获取类相关信息,实例可以获取类方法但不推荐。
  • 静态方法:没有特殊形参,带有装饰器 staticmethod,通过类名调用,实例可以访问但不推荐,项目的辅助类一般使用静态方法。
class Person:
    MAX_ACE = 100  # 类属性,最大值
    MIN_ACE = 0    # 类属性,最小值

    @classmethod
    def from_birth_year(cls, name, birth_year):
        current_year = 2024  # 假设当前年份是 2024
        age = current_year - birth_year
        return cls(name, age)  # 返回一个新的 Person 实例

    @staticmethod
    def is_adult(age):
        return age > 18  # 静态方法,判断是否成年

    def __init__(self, name, age):
        self.name = name  # 实例属性,姓名
        self.age = age    # 实例属性,年龄

    def __str__(self):
        return f"名字:{self.name}, 年龄:{self.age}"  # 返回对象描述的字符串


    def set_name(self, name):
        self.name = name  # 设置姓名的实例方法

    def get_name(self):
        return self.name  # 获取姓名的实例方法


# 创建一个 Person 对象
p0 = Person("张飞", 20)
# 输出对象的 name 和 age 属性
print(p0.name, p0.age)  # 输出: 张飞 20
# 使用 __str__ 方法打印对象的字符串表示
print(p0)  # 输出: 名字:张飞, 年龄:20
# 使用 set_name 方法修改 name 属性
p0.set_name("关羽")
# 再次打印对象的字符串表示和获取名字
print(p0, p0.get_name())  # 输出: 名字:关羽, 年龄:20

# 访问类属性
print(Person.MAX_ACE)  # 输出: 100
print(Person.MIN_ACE)  # 输出: 0

# 修改类属性
Person.MIN_ACE = 10
print(Person.MIN_ACE)  # 输出: 10

# 通过实例访问类属性(不推荐这样做)
print(p0.MIN_ACE, p0.MAX_ACE)  # 输出: 10 100

# 尝试通过实例修改类属性(这不会修改类的属性,而是创建了一个实例属性)
p0.MAX_ACE = 200
print(Person.MIN_ACE, p0.MAX_ACE)  # 输出: 10 200

# 使用类方法创建 Person 对象
p2 = Person.from_birth_year("关羽", 1990)
print(p2)  # 输出: 名字:关羽, 年龄:34

# 使用静态方法判断年龄是否成年
print(Person.is_adult(20))  # 输出: True
print(Person.is_adult(15))  # 输出: False


八.动态添加内容

Python 的动态性允许在运行时向类中添加新的属性、方法等。

import types


class Person:
    pass


# # 在实例上添加属性  向实例中添加实例数据  其他实例无影响
p0 = Person()
p = Person()
p.name = "赵云"
print(p.name)


# 添加实例方法  # 向实例中添加实例数据 其他实例无影响
def my_set_name(self, name):
    self.name = name


p.set_name = types.MethodType(my_set_name, p)
p.set_name("关羽")
print(p.name)
# 向类中添加类属性  类可以正常访问 所有实例均可访问
Person.MAX_AGE = 120
print(Person.MAX_AGE, p.MAX_AGE, p0.MAX_AGE)


@classmethod
def my_info(cls):
    print(cls.__bases__)


# 向类中添加类方法  方法格式符合类方法格式  类与所有实例均可访问
Person.info = my_info
Person.info()
p0.info()
p.info()


@staticmethod
def my_max(x, y):
    return x if x > y else y


#  向类中添加静态方法  方法要符合静态方法格式  类与实例均可访问
Person.max = my_max

print(Person.max(10, 20), p.max(50, 100), p0.max(200, 500))


九.数据的访问级别
  • 公有:普通名字,类内、类外、子类都可以使用。。
  • 私有:以双下划线 __ 开头的属性或方法,在类外部不能直接访问,但可以通过类的公有方法间接访问。
  • 保护(Python 中不严格区分):以单下划线 _ 开头的属性或方法,遵在类内可以访问,在子类可以访问,在类外可强制访问。
"""
数据的访问级别
	公有类型
		public
		普通名字
		类内和类外,子类都可以使用
	私有类型
		private
		以_ _开头
		只能在类内访问
	保护类型
		protect
		在类内可以访问
		在子类中可以访问
		在类外可以强制访问
"""


class Person:
    def __init__(self, name, age, sex):
        self.name = name
        self.__age = age
        self._sex = sex

    def _set_sex(self, sex):
        self._sex = sex

    def _get_sex(self):
        return self._sex

    def __set_age(self, age):
        self.__age = age

    def __get_age(self):
        return self.__age

    def get_name(self):
        return self.name

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

    def __str__(self):
        return f"name:{self.name},age:{self.__age},sex:{self._sex}"


# 公有
p0 = Person("张飞", 20, "男")  # 私有只能在类内访问 age
print(p0)
p0.set_name("张菲菲")
print(p0.name, p0.get_name())
# 保护
p0._set_sex("女")
print(p0._get_sex())
十.属性封装与 property
  • 口头称呼:类封装数据与操作,属性与行为,包括类属性、实例属性、公有属性、私有属性、保护属性。
  • property :包括 fget(获取触发,@property)和 fset(设置触发,@属性名.setter)装饰器。
class Person:
    def __init__(self, name, age, sex, height):
        self.__name = name
        self.age = age
        self.__sex = sex
        self.__height = height

    @property
    def height(self):
        return self.__height

    @height.setter
    def height(self, height):
        self.__height = height

    def __get_sex(self):
        return self.__sex

    def __set_sex(self, sex):
        if sex in ["男", "女"]:
            self.__sex = sex
        else:
            print("设置失败")

    # 封装真正的属性
    sex = property(__get_sex, __set_sex)

    def get_name(self):
        return self.__name

    def set_name(self, name):
        if 2 <= len(name) <= 4:
            self.__name = name
        else:
            print("设置失败")


p = Person("张飞", 20, "男", 190)

# 获取 设置age 直接使用 (容易产生不合法数据)
print(p.age)
p.age = -30
print(p.age)
print("=============================")
# 获取设置name 需要通过函数  数据安全
print(p.get_name())
p.set_name("赵云")
print(p.get_name())
print("=============================")
# 使用 property 获取和设置 sex
print(p.sex)
p.sex = "其他"
print(p.sex)
print("=============================")
print(p.height)
p.height = 200
print(p.height)


十一.单例模式
  • 只有一个实例,通过控制构造函数判定是否需要重新生成实例,第一次生成后放入类属性,以后返回第一次生成的实例。
class Person:
    pass


# 每次调用类都可以生成一个新的实例
p1 = Person()
p2 = Person()
p3 = Person()

print(p1 is p2, p2 is p3, p3 is p1)


class Manage(object):
    instance = None

    def __new__(cls, *args, **kwargs):
        """
        对构造函数进行控制 不是每次都生成新的实例
        1. 对类属性instance判断 如果为空 就构造一个实例 并且把实例赋予instance
        2. 对类属性instance判断 如果不为空 则直接把他返回
        """
        if not Manage.instance:
            Manage.instance = super().__new__(cls)
        return Manage.instance

    def __init__(self):
        """初始化函数 初始化实例 向self中添加内容"""
        print(f"初始化函数执行了")


m1 = Manage()
m2 = Manage()
print(m1 is m2, m1 is None, m2 is None)


class BaseManage:
    def __new__(cls, *args, **kwargs):
        if not hasattr(BaseManage, "instance"):
            obj = super().__new__(cls)
            setattr(BaseManage, "instance", obj)

        return getattr(BaseManage, "instance")


m1 = BaseManage()
m2 = BaseManage()
print(m1 is m2)


class SystemManage(BaseManage):
    pass


sm1 = SystemManage()
sm2 = SystemManage()
print(sm1 is sm2)
print(isinstance(sm1, SystemManage), isinstance(sm1, BaseManage))



 

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

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

相关文章

昇思25天学习打卡营第25天 | Pix2Pix实现图像转换

Pix2Pix实现图像转换 Pix2Pix概述 Pix2Pix是一种基于条件生成对抗网络&#xff08;cGAN, Condition Generative Adversarial Networks&#xff09;的图像转换模型&#xff0c;由Phillip Isola等人在2017年提出。它能够将语义/标签图像转换为真实图片、灰度图转换为彩色图、航空…

永劫无间:排位赛游戏攻略大全!VMOS云手机辅助攻略!

在《永劫无间》中&#xff0c;排位赛和金乌玩法是提升实力和展示技巧的绝佳途径。以下是详细的攻略建议&#xff0c;帮助玩家在游戏中取得更好的成绩。 排位赛 英雄们齐聚“聚窟洲”&#xff0c;为争夺“不朽面具”展开激烈的战斗。排位赛是玩家展示实力的重要平台&#xff0c…

六方云笔试总结

1. &#xff08;1&#xff09;题目 外部变量&#xff0c;指的是处于函数外部的全局静态变量&#xff0c;所以选c &#xff08;2&#xff09;知识点 1. static &#xff08;1&#xff09;函数外部的全局变量 当一个变量在函数外部定义并使用static关键字修饰时&#xff0c;这…

函数的学习(二)

1.函数嵌套 在C语言中&#xff0c;函数的嵌套是指在一个函数内部调用另一个函数。通过函数的嵌套&#xff0c;可以将程序的功能细化&#xff0c;提高代码的可读性和可维护性。函数的嵌套可以是直接嵌套&#xff0c;也可以是间接嵌套。 直接嵌套是指一个函数直接在另一个函数内…

华彩38载 同心筑未来—中华财险客户节盛大启幕!

活动主题&#xff1a;华彩38载 同心筑未来—中华财险客户节金融知识有奖问答 活动时间&#xff1a;2024年7月26日至9月15日 参与方式&#xff1a;① 微信搜索并关注公众号“中华财险宁波分公司”进入答题活动页面&#xff0c;点击“开始答题”即可开始答题&#xff1b;②规定…

ComfyUI-MuseTalk部署依赖mmcv

ComfyUI-MuseTalk部署依赖mmcv ComfyUI-MuseTalk是MuseTalk基于ComfyUI的自定义节点插件。MMPose 是一款基于 PyTorch 的“人体姿态”分析的开源工具箱&#xff0c;是 OpenMMLab 项目的成员之一。OpenMMLab 团队致力于构建了深度学习时代最具影响力的开源计算机视觉算法系统&am…

【C++标准库】介绍及使用string类

string 一.string类介绍二.string类的静态成员变量三.string类的常用接口1.构造函数&#xff08;constructor&#xff09;2.析构函数&#xff08;destructor&#xff09;3.运算符重载&#xff08;operator&#xff09;1.operator2.operator[]3.operator4.operator 4.string的四…

SecureCrt设置豆沙绿

绿豆沙色能有效的减轻长时间用电脑的用眼疲劳&#xff01; 色调&#xff1a;85&#xff0c;饱和度&#xff1a;123&#xff0c;亮度&#xff1a;205&#xff1b;RGB颜色红&#xff1a;199&#xff0c;绿&#xff1a;237&#xff0c;蓝&#xff1a;204&#xff1b; 十六进制颜色…

3步阐述搜索框做了什么事情

搜索功能是几乎每个产品的通用标配功能&#xff0c;一个看似简单的搜索框背后&#xff0c;其实隐含了大量的设计思考和技术壁垒。本文将从三个部分阐述&#xff0c;为何搜索框并不简单。 本文将从搜索场景的思考、基于步骤的搜索设计以及搜索数据的追踪3个部分&#xff0c;对产…

今日arXiv最热大模型论文:北京大学最新综述:视觉大模型中的漏洞与攻防对抗

近年来&#xff0c;视觉语言大模型&#xff08;LVLM&#xff09;在文本转图像、视觉问答等任务中大放异彩&#xff0c;背后离不开海量数据、强大算力和复杂参数的支撑。 但是&#xff01;大模型看似庞大的身躯背后却有一颗脆弱的“心脏”&#xff0c;极易受到攻击。攻击者可以…

史上最全,网工必考证书大盘点,竟然有20多个?

最近很多朋友来咨询&#xff0c;作为网工能考什么证书&#xff1f;证书那么多要怎么选择&#xff1f;哪个性价比高、哪个回报大等等等等的问题。 不难看出&#xff0c;大家最近这个想要学习和提升的势头很猛&#xff0c;毕竟现在这个环境下&#xff0c;属实是不好过了&#xff…

FPGA开发——数码管的使用(二)

一、概述 在上一篇文章中我们针对单个数码管的静态显示和动态显示进行了一个设计和实现&#xff0c;这篇文章中我们针对多个数码管同时显示进行一个设计。这里和上一篇文章唯一不同的是就是数码管位选进行了一个改变&#xff0c;原来是单个数码管的显示&#xff0c;所以位选就直…

Android Studio运行报错:module java.base dose not “opens java.io“ to unnamed module

今天第一次使用Android Studio运行一个安卓工程&#xff0c;报如图错误,应该是环境问题。 解决&#xff1a; 右上角的设置图标->settings->Buid,Execution,Deployment->Build Tools->Gradle->Gradle JDK->选择本地环境的java_home jdk&#xff08;怎么安装…

docker镜像不可用

现在阿里、163等docker镜像基本不能使用&#xff0c;不能pull镜像了。 1.腾讯云内部 腾讯云服务器内部可用镜像&#xff08;当然&#xff0c;需要先有一个腾讯云服务器&#xff09;&#xff1a;https://mirror.ccs.tencentyun.com 配置方法&#xff0c;vi /etc/docker/daemon…

C++—— IO流

一、C语言的输入与输出 C语言中我们用到的最频繁的输入输出方式就是scanf()和printf()。 scanf()&#xff1a;从标准输入设备&#xff08;键盘&#xff09;中读取数据&#xff0c;并将值存放在变量中。 printf()&#xff1a;将指定的文字/字符串输出到标准输出设备&#xff08;…

Python 聊天机器人项目-8-学习使用 NLTK 和 Keras 构建您的第一个聊天机器人

一、前言 该文章仅作为个人学习使用 二、正文 项目源代码&#xff1a;Python 聊天机器人项目 - 学习使用 NLTK 和 Keras 构建您的第一个聊天机器人 - DataFlair (data-flair.training) 数据集&#xff1a;https://data-flair.training/blogs/download-python-chatbot-data-…

Web3时代:科技与物联网的完美结合

随着信息技术的不断进步和物联网应用的普及&#xff0c;Web3技术作为下一代互联网的重要组成部分&#xff0c;正逐渐与物联网技术深度融合&#xff0c;共同开创了新的科技时代。本文将深入探讨Web3技术与物联网的结合&#xff0c;探索它们如何共同推动未来科技发展的新趋势和应…

【32单片机篇】项目:智能排队控制系统

一、项目需求 1. 红外传感器检测有人通过并计数&#xff1b; 2. 计数值显示在LCD1602&#xff1b; 3. 允许通过时&#xff0c;LED1闪烁&#xff0c;蜂鸣器不响&#xff0c;继电器不闭合&#xff1b; 4. 不允许通过时&#xff0c;LED2闪烁&#xff0c;蜂鸣器响&#xff0c;继电…

工信部:2024上半年我国信息安全领域收入909亿元

2024年上半年软件业经济运行情况 上半年&#xff0c;我国软件和信息技术服务业&#xff08;以下简称“软件业”&#xff09;运行态势良好&#xff0c;软件业务收入和利润均保持两位数增长&#xff0c;软件业务出口收入增速由负转正&#xff0c;主要大省持续向好发展。 一、总…

光纤基础科普

这部分主要介绍光纤的常见接口&#xff08;四种&#xff09;、光纤传输的种类、光模块的封装类型。 文章目录 一、光纤的常见接口二、光模块封装三、光纤传输种类 一、光纤的常见接口 光纤接口种类繁多&#xff0c;这里给出常用的四种 &#xff08;1&#xff09;SC 型光纤接…