快速掌握——python类 封装[私有属性方法]、继承【python进阶】(内附代码)

1.类的定义 与 实例化对象

在python中使用class关键字创建一个类。

举例子

class Stu(object):
    id = '1001'
    name = '张三'
    def __init__(self):
        pass
    def fun1(self):
        pass

# 实例化对象
s1 = Stu()
s2 = Stu()
print(s1.name)
print(s2.name)

第一个方法 __init__是一种特殊的方法,称为构造函数或者初始化函数,并不是必须的,需要的时候添加即可。

第二个 self参数表示的是实例化对象的id号,每次调用的时候self和对象的id号进行自动绑定。

1.1.访问属性/方法

使用符号 . 进行访问

    # 访问属性

       对象名.属性

    # 访问方法

       对象名.方法名()

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

    def introduce(self):
        print(f"我的名字是 {self.name},我今年 {self.age} 岁。")

# 创建Person类的一个实例
person1 = Person("张三", 30)

# 调用实例的方法
                        # 访问属性
person1.age=60          #对象名.属性

                         # 访问方法
person1.introduce()     #对象名.方法名()

还可以使用以下函数的方式来访问属性:

  • getattr(obj, name[, default]) : 访问对象的属性。
  • hasattr(obj,name) : 检查是否存在一个属性。
  • setattr(obj,name,value) : 设置一个属性。如果属性不存在,会创建一个新属性。
  • delattr(obj, name) : 删除属性。

1.2 对象与类的关系

  1. 对象拥有    的    所有属性和方法
  2. 对象的  属性和方法  可以   单独添加、删除、修改
  3. 对象与对象之间的属性和方法不可共享
  4. 对象不能独自创建,必须依托于类,类可以实例化N个对象
class Stu(object):
    id = '1001'
    name = '张三'
    def fun1(self):
        pass

# 实例化对象
s1 = Stu()
s2 = Stu()
# 对象的属性可以单独修改、添加、删除
s1.name = '李四'
s1.age = 18
del s1.age
print(s1.name)
# print(s1.age)
print(s2.name)
# print(s2.age)

1.3 魔方方法——构造函数 与 析构函数

        魔方方法是一种特殊的命名约定,它们以双下划线开始和结束。这些方法在特定的条件下会被Python解释器自动调用为Python类添加了动态的、面向对象的行为

  1. __init__ 构造函数:完成对象的初始化工作,方便统一管理、调用类创建对象时,自动执行。
  2. __del__ 析构函数:删除对象时执行一些操作,自动执行。
  3. __str__ 打印方法:输出执行信息,自动执行。
class Car(object):
    def __init__(self, name, color):
        self.name = name
        self.color = color

    def __str__(self):
        return f"车品牌{self.name} 颜色{self.color}"

    def __del__(self):
        print(f"{self.name}报废了,去车管所吧")


c1 = Car("奥迪", "黑色")
c2 = Car("小米su7", "紫色")

print(c1.name, c2.name)
print(c1)
print(c2)
# print(str(c1))

_init__(self[, ...]): 构造器方法,当创建一个新对象时被调用,用于初始化对象。

__del__(self): 析构器方法,当对象被销毁之前被调用,用于清理资源。
__str__(self): 返回对象的字符串表示形式,常用于 print() 函数或 str() 函数。
__repr__(self): 返回一个准确无误的字符串表示形式,用于调试或开发,比 __str__ 更加详细
__len__(self): 定义当对对象使用 len() 函数时的行为,返回容器的长度。
__getitem__(self, key): 实现了对象的索引访问,如 my_obj[key]。
__setitem__(self, key, value): 允许设置对象的索引值,如 my_obj[key] = value。

__iter__(self): 使对象成为可迭代的,返回一个迭代器对象。

__next__(self): 在迭代器中定义 next() 行为,返回下一个值。

__call__(self[, args...]): 使得对象可以像函数一样被调用,例如 my_obj().

__add__(self, other): 定义加法操作符 + 的行为,如 my_obj + other_obj。
__eq__(self, other): 定义等于运算符 == 的行为,用于比较两个对象是否相等

1.4 类属性/方法 与 实例对象属性/方法 与 静态方法

属性: 

class Student(object):
    """
    定义了一个学生类
    """
    grade = 'py24101'       # 类属性

    def __init__(self, name, age):
        self.name = name    # 实例对象属性
        self.age = age      # 实例对象属性

s1 = Student('张三', 18)

# 类属性的访问
print(Student.grade)
print(s1.grade)

# 实例属性的访问
# print(Student.name)    报错!!!
                        #类 不能访问 实例对象的属性
                        #相当于闭包,内可以访问外,外不能访问内
print(s1.name)
class Bank(object):
    """
    定义了一个银行卡类,用于初始化、存钱、取钱
    """
    total_money = 0

    def __init__(self, name, money):
        self.name = name
        Bank.total_money += money    #改为self.
                                        #Bank.total_money 通过类 调用 类属性
    def save(self, money):               #self.total_money 通过对象 调用 类属性
        Bank.total_money += money

    def draw(self, money):
        Bank.total_money -= money

b1 = Bank('张三', 1000)
print(b1.total_money)
b1.save(5000)
print(b1.total_money)
b1.draw(3000)
print(b1.total_money)

b2 = Bank('李四', 8888)
print(b2.total_money)
b2.save(10000)
print(b2.total_money)

类方法、实例方法、静态方法:

class Student(object):
    """
    定义了一个学生类
    """
    grade = 'py24101'

    @classmethod
    def cls_fun(cls):
        """类方法中只能调用类属性和类方法"""
        print(f"班级名称是{cls.grade}")

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

    def fun1(self):
        """实例方法中能调用类属性、实例属性"""
        print(f"实例方法中输出类属性{self.grade}, 输出实例属性{self.name}")

    @staticmethod
    def sta_fun(x):
        print(f"{x}静态方法一般实现与类和对象无关联的操作,例如:游戏说明书等")

s1 = Student('张三', 18)
# 如何调用类方法
Student.cls_fun()
s1.cls_fun()

# 如何调用实例方法
Student.fun1(s1)
s1.fun1()

# 如何调用静态方法
Student.sta_fun(3)
s1.sta_fun(3)

1.5 Python的内置类属性

  • __dict__ : 类的属性(包含一个字典,由类的数据属性组成)
  • __doc__ :类的文档字符串
  • __name__: 类名
  • __module__: 类定义所在的模块(类的全名是'__main__.className',如果类位于一个导入模块mymod中,那么className.__module__ 等于 mymod)
  • __bases__ : 类的所有父类构成元素(包含了一个由所有父类组成的元组)
class Student(object):
    """
    定义一个学生类
    属性:名字 年龄
    方法:method_1 method_2
    """
    name = '张三'
    age = 18

    def method_1(self):
        pass

    def method_2(self):
        pass

print(Student.__dict__)
print(Student.__doc__)
print(Student.__name__)
print(Student.__module__)
print(int.__module__)
print(Student.__bases__)

2.类的封装【私有属性与方法】

封装指的是隐藏对象中一些不希望让外部所访问的属性或方法

python中封装是通过设置访问权限来体现的,私有属性私有方法控制访问权限的组成部分。

2.1 私有属性

              在类的内部使用,不希望外部直接访问的变量

              在python中,使用双下划线作为前缀定义私有属性

              私有属性在类外不能访问

class Bank(object):
    """
    定义了一个银行卡类
    属性:name     pwd密码【我不希望外部访问】
    """
    def __init__(self, name, pwd):
        self.name = name
        self.__pwd = pwd

    # 为了在某些需要的时候,访问到私有属性,所以需要在类内部设置两个接口
    def get_pwd(self):
        return self.__pwd

    def set_pwd(self, newpwd):
        self.__pwd = newpwd


# print(Bank.__pwd)

b1 = Bank('张三', '123456')
print(b1.name)
# print(b1.__pwd)
print(b1.get_pwd())
b1.set_pwd('666888')
print(b1.get_pwd())

2.2 私有方法

和私有属性是一样的。

class Bank(object):
    """
    定义了一个银行卡类
    属性:name     pwd密码【我不希望外部访问】
    """
    def __init__(self, name, pwd):
        self.name = name
        self.__pwd = pwd

    def __info(self):
        print(f"名字{self.name}, 密码{self.__pwd}")

    def get_info(self):
        self.__info()

# Bank.__info() 报错
b1 = Bank('李四', '123456')
# b1.__info()   报错
b1.get_info()

2.3 属性装饰器

        属性装饰器是实现把方法转为属性的装饰器

作用:

                1.  把方法转为属性,便于操作属性

                2 . 实现对属性的更改(验证)、查看、删除

语法格式:

class 类名(object):

        def __init__(self):

                self.__名字 = xxx

        @property def 函数名(self):

                return self.__名字

        @函数名.setter def 函数名(self, m):

                self.__名字 += m

class Car(object):
    def __init__(self, name, color):
        self.name = name
        self.color = color
        self.__num = 20

    @property
    def num(self):
        return self.__num

    @num.setter
    def num(self, x):
        self.__num += x

c1 = Car('法拉利', '红色')
print(c1.name, c1.color, c1.num)
c1.num = 80
print(c1.num)

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

    @property
    def name(self):
        return self.__name

    @name.setter
    def name(self, new_name):
        if not isinstance(new_name, str):
            print('名字必须是一个字符串')
        else:
            self.__name = new_name

    @name.deleter
    def name(self):
        print("已删除名字")
        del self.__name

s1 = Student('张三')
print(s1.name)
s1.name = 111
s1.name = '华清远见'
print(s1.name)
del s1.name

3.类的继承

                        面向对象的编程带来的主要好处之一就是代码的重用,

                        实现这种重用的方法之一就是通过继承机制。

                        通过继承创建的新类称之为【子类】或者【派生类】,

                        被继承的类称之为【父类】、【基类】、【超类】。

3.1 继承语法格式

class  子类名(父类名列表):
    pass
class Parent(object):
    """
    定义父类
    """
    par_attr = 100

    def __init__(self):
        print("初始化父类")

    def par_fun1(self):
        print("父类方法1")

    def par_fun2(self):
        print("父类方法2")

class Child(Parent):
    """
    定义子类
    """
    child_attr = 666
    def __init__(self):
        print("初始化子类")

    def child_fun1(self):
        print("子类方法1")

c1 = Child()
print(c1.child_attr)
c1.child_fun1()

print(c1.par_attr)
c1.par_fun1()
c1.par_fun2()

3.2 多继承语法【不建议乱用】

如果在继承的元组()里面有一个以上的类,就称之为多继承。

# python中提供了一个函数mro()用于查看继承的顺序

class A:
    pass

class B:
    pass

class C:
    pass

class D(A, B, C):
    pass

d1 = D()
print(D.mro())

3.3 继承重写父类方法

如果你的父类方法不能满足你得要求,你可以在之类中重写父类的方法。

class Parent(object):
    def method(self):
        print(f"{self}的方法")

class Child(Parent):
    pass

c = Child()
c.method()


# 重写
class Parent(object):
    def method(self):
        print(f"{self}的方法")

class Child(Parent):
    def method(self):
        print("xxxxxxxxxx")
        print(f"{self}的方法")

c = Child()
c.method()

这里列出了一些通用的功能,可以在自己的类重写:

  1. __init__ ( self [,args...] ) 构造函数 简单的调用方法: obj = className(args)
  2. __del__( self ) 析构方法, 删除一个对象 简单的调用方法 : del obj
  3. __repr__( self ) 转化为供解释器读取的形式 简单的调用方法 : repr(obj)
  4. __str__( self ) 用于将值转化为适于人阅读的形式 简单的调用方法 : str(obj)
  5. __cmp__ ( self, x ) 对象比较 简单的调用方法 : cmp(obj, x)

3.4 python继承特点

  • 在子类中如果需要父类的构造方法,需要显式调用父类的构造方法,或者不重写父类的构造方法。__init__()
  • 在子类中调用父类的方法,需要显式调用,且第一个参数self不能省略。
class Parent(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def method(self):
        print(f"{self}的方法")

class Child(Parent):
    def fun1(self):
        print(self.x , self.y)
# 不重写父类构造方法
c = Child(1, 2)
c.fun1()

class Parent(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def method(self):
        print(f"{self}的方法")

class Child(Parent):
    def __init__(self, x, y, z):
        Parent.__init__(self, x, y)
        self.z = z

    def fun1(self):
        print(self.x , self.y, self.z)

# 重写父类构造方法、里面显式调用父类构造方法
c = Child(1, 2, 33)
c.fun1()
class Parent(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y

class Child(Parent):
    def __init__(self, x, y, z):
        super().__init__(x, y)
        self.z = z

    def add(self):
        return self.x + self.y + self.z

c = Child(1, 1, 1)
print(c.add())
class Parent(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def add(self):
        return self.x + self.y

class Child(Parent):
    def __init__(self, x, y, z):
        super().__init__(x, y)
        self.z = z

    def add(self):
        return super().add() + self.z

c = Child(1, 1, 1)
print(c.add())

3.5 运算符重载

在Python中,并没有像其他语言(如C++)中那样的内置机制来重载运算符。但是,你可以通过定义特定的方法来模拟运算符重载的行为。

以下是一些常见运算符以及它们对应的特殊方法:

加法:+ 对应 __add__

减法:- 对应 __sub__
乘法:* 对应 __mul__
除法:/ 对应 __truediv__
取模:% 对应 __mod__
幂运算:** 对应 __pow__
位运算:<< 对应 __lshift__
位运算:>> 对应 __rshift__
位运算:| 对应 __or__

位运算:& 对应 __and__

位运算:^ 对应 __xor__
class Operator(object):
    def __init__(self, x):
        self.x = x

    def __add__(self, other):
        return self.x + other.x * 3

o1 = Operator(1)
o2 = Operator(3)
print(o1 + o2)
class Operator(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __add__(self, other):
        return self.x * other.x + self.y * other.y

o1 = Operator(1, 2)
o2 = Operator(3, 4)
print(o1 + o2)

4.类的多态

python中的多态也可以通过方法重写进行。

同一个方法,不同对象显式的结果不同。

class Animal(object):
    name = '动物'
    age = 0
    def speak(self):
        print("动物的声音")

class Dog(Animal):
    def speak(self):
        print("汪汪汪")

class Cat(Animal):
    def speak(self):
        print("喵喵喵")

a = Animal()
d = Dog()
c = Cat()

a.speak()
d.speak()
c.speak()

5. 关于下划线说明

  1. __foo__: 以双下划线开头双下划线结尾,定义的是特殊方法,一般是系统定义名字

                        类似 __init__() 之类的,自动。

  1. _foo: 以单下划线开头的表示的是 protected 类型的变量,即保护类型只能允许其本身与子类进行访问,不能用于 from module import ···
  2. __foo: 双下划线的表示的是私有类型(private)的变量, 只能是允许这个类本身进行访问了。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

51c自动驾驶~合集10

我自己的原文哦~ https://blog.51cto.com/whaosoft/11638131 #端到端任务 说起端到端&#xff0c;每个从业者可能都觉得会是下一代自动驾驶量产方案绕不开的点&#xff01;特斯拉率先吹响了方案更新的号角&#xff0c;无论是完全端到端&#xff0c;还是专注于planner的模型&a…

BFS 算法专题(三):BFS 解决边权为 1 的最短路问题

目录 1. 迷宫中离入口最近的出口 1.1 算法原理 1.2 算法代码 2. 最小基因变化 ★★★ 2.1 算法原理 2.2 算法代码 3. 单词接龙 3.1 算法原理 3.2 算法代码 4. 为高尔夫比赛砍树 (hard) 4.1 算法原理 4.2 算法代码 1. 迷宫中离入口最近的出口 . - 力扣&#xff08;…

Flink_DataStreamAPI_执行环境

DataStreamAPI_执行环境 1创建执行环境1.1getExecutionEnvironment1.2createLocalEnvironment1.3createRemoteEnvironment 2执行模式&#xff08;Execution Mode&#xff09;3触发程序执行 Flink程序可以在各种上下文环境中运行&#xff1a;我们可以在本地JVM中执行程序&#x…

46.第二阶段x86游戏实战2-拆解自动打怪流程

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 本人写的内容纯属胡编乱造&#xff0c;全都是合成造假&#xff0c;仅仅只是为了娱乐&#xff0c;请不要…

解决C盘空间不足的三种方案

方案一&#xff1a;网上盛传的C盘磁盘碎片整理&#x1f9e9;&#xff08;原理&#xff1a;将分散的文件片段整理到相邻的磁盘区域&#xff0c;减少文件的碎片化程度&#xff09;(效果不明显) 方案二&#xff1a;把其他盘的空间给C盘 &#x1f4bd;&#xff08;效果显著&#xf…

同一套SDK 兼容第二块板卡

尽可能分开写,避免兼容性变差

计算机网络高频八股文面试题及参考答案

请简述 TCP 和 UDP 的区别&#xff1f; TCP&#xff08;传输控制协议&#xff09;和 UDP&#xff08;用户数据报协议&#xff09;是两种不同的传输层协议&#xff0c;它们有以下区别。 从连接方式上看&#xff0c;TCP 是面向连接的协议。在通信之前&#xff0c;需要通过三次握手…

前缀和算法习题篇(上)

1.一维前缀和 题目描述&#xff1a; 解法一&#xff1a;暴力解法&#xff1a;模拟 时间复杂度是O(n*q),会超时。 解法二&#xff1a;前缀和解法&#xff1a;快速求出数组中某一个连续区间的和 快速是指O(1),前缀和思想可把时间复杂度可降到O(q)。 算法思路&#xff1a; 先预处…

uniapp路由与页面跳转详解:API调用与Navigator组件实战

UniApp路由与页面跳转详解&#xff1a;API调用与Navigator组件实战 路由 uniapp页面路由为框架统一管理&#xff0c;开发者需要在page.json里面配置每个路由页面的路径及页面样式。 路由跳转 uniapp有两种页面路由跳转方式&#xff0c;调用API跳转和navigator组件跳转。 调…

linux-DNS解析

dns解析 dns&#xff1a;域名系统&#xff0c;将域名和ip地址互相映射的一个分布式的数据库&#xff0c;方便用户访问互联网。 ip地址&#xff1a;是所有设备和网站在互联网上的唯一地址&#xff0c;通信一定是ip和ip之间的通信。 dns解析&#xff1a;根据域名在互联网当中找…

Playwright 快速入门:Playwright 是一个用于浏览器自动化测试的 Node.js 库

Playwright 是一个用于浏览器自动化测试的 Node.js 库&#xff0c;它支持 Chromium, Firefox 和 WebKit 浏览器引擎。Playwright 提供了一套强大的 API 来进行网页自动化测试&#xff0c;包括页面导航、元素选择、表单提交等操作&#xff0c;并且能够处理现代网页中的异步加载内…

【maven踩坑】一个坑 junit报错 但真正导致这个的不是junit的原因

目录 事件起因环境和工具操作过程解决办法结束语 事件起因 报错一&#xff1a; Internal Error occurred. org.junit.platform.commons.JUnitException: TestEngine with ID junit-vintage failed to discover tests报错二&#xff1a; Internal Error occurred. org.junit.pl…

ONNX: export failure: DLL load failed while importing _message: 找不到指定的程序。

ONNX: export failure 问题其他解决快速解决 问题 使用pytorch导出onnx&#xff08;Open Neural Network Exchange&#xff09;模型&#xff0c;结果使用conda安装完onnx之后&#xff0c;问题就出现了 ONNX: export failure: DLL load failed while importing _message: 找不到…

Redis做分布式锁

&#xff08;一&#xff09;为什么要有分布式锁以及本质 在一个分布式的系统中&#xff0c;会涉及到多个客户端访问同一个公共资源的问题&#xff0c;这时候我们就需要通过锁来做互斥控制&#xff0c;来避免类似于线程安全的问题 因为我们学过的sychronized只能对线程加锁&…

用Tokio掌握Rust异步编程

在Rust中构建可伸缩且高效的应用程序时&#xff0c;异步编程必不可少。异步编程能显著提高性能&#xff0c;让代码在不阻塞的情况下并发处理多个任务。在本教程中&#xff0c;我们将探索Tokio&#xff0c;介绍异步编程原理及应用场景&#xff0c;并逐步带你编写异步代码。 Toki…

推荐一款3D建模软件:Agisoft Metashape Pro

Agisoft Metashape Pro是一款强大的多视点三维建模设计辅助软件&#xff0c;Agisoft Metashape是一款独立的软件产品&#xff0c;可对数字图像进行摄影测量处理&#xff0c;并生成3D空间数据&#xff0c;用于GIS应用&#xff0c;文化遗产文档和视觉效果制作&#xff0c;以及间接…

记录日志中logback和log4j2不能共存的问题

本文章记录设置两个日志时候&#xff0c;控制台直接报错 标黄处就是错误原因&#xff1a;1. SLF4J(W)&#xff1a;类路径包含多个SLF4J提供程序。 SLF4J(W)&#xff1a;找到提供程序[org.apache.logging.slf4j. net]。 SLF4J(W)&#xff1a;找到提供程序[ch.qos.log .classi…

【论文阅读】Virtual Compiler Is All You Need For Assembly Code Search

阅读笔记:Virtual Compiler Is All You Need For Assembly Code Search 1. 研究背景 逆向工程:逆向工程需要在庞大的二进制文件中快速定位特定功能(例如恶意行为)。传统方法依赖于经验和启发式算法,效率低下。汇编代码搜索:通过自然语言搜索汇编代码功能,能够更高效地处…

洛古---越狱问题【快速幂】

今天和大家讲一个洛古的算法题&#xff0c;我觉得还是比较有含金量的&#xff0c;今天给大家分享一下 题目描述 监狱有 &#x1d45b;n个房间&#xff0c;每个房间关押一个犯人&#xff0c;有 &#x1d45a; 种宗教&#xff0c;每个犯人会信仰其中一种。如果相邻房间的犯人的宗…

Python3.11.9+selenium,选择证书用多线程+键盘enter解决

Python3.11.9+selenium,选择证书用多线程+键盘enter解决 1、遇到问题:弹出证书选择,无法点击确定 import pyautogui pyautogui.press(enter) 键盘enter也无法点击 2、解决办法:用多线程解决同时执行click链接和Enter点击证书的确定 1、点击操作 # # 通过文本链接文本…