python核心阶段(三)—— 类、属性、方法的补充知识

本文详细解析了Python中的元类概念,元类的应用场景,类对象的创建机制,以及私有属性、只读属性的实现与访问权限。还介绍了特殊方法如__setattr__、__str__等在类和对象中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 .类相关补充

 1.1 元类

  • 概念:创建类对象的类

   对象由类产生,而类也是一个对象,所以类对象是由另外一个类产生出来的,这个类就是元类

元类结构示意图

 1.2 类对象的创建方式

  • 利用type()函数 / 元类

        type有两个作用:

        第一个作用是直接输入对象,便可调出该对象的数据类型

        第二个作用就是作为元类创建类对象

  • 语法:   变量名 = type(类名str,父类tuple,方法属性dict           

               类名:存储在类中的类的名称,为字符串,若不指定,需传入空字符串:“ ”   

               父类:新创建的类可以继承父类的一些特点(属性、方法等)

                          以元组形式传入,若没有父类要传入空元组:(),默认继承object

               绑定的方法属性:需要以字典键值对形式传入

               变量名:只起调用类的作用,可以与类名相同,调用时应输入变量名,而不是类名

  • 元类的查找机制 / 类创建流程 

       在用type创建类时,

  1. 会先在自身通过__metaclass__属性查找是否有指定元类,若有则通过这个元类来创建
  2. 若没有,再检测父类中是否存在__metaclass__属性
  3. 若没有,再检测模块中是否存在__metaclass__属性
  4. 若以上三者均不存在,则通过内置的type元类来创建新的类对象
类对象创建时,元类查找流程

        

 1.3 元类的应用场景(作用)

  1.  拦截类的创建
  2. 修改类
  3. 返回修改之后的类

 1.4 类的描述(注释)

  • 注释的作用

         在创建了类之后,添加相应的注释,可以方便我们去理清整个模块的思路

  • 描述方式(类似函数)

         直接在类或者方法的下面,使用三个双引号 """  """ 跨行书写,规范如下:

class Person:
    """
    这里写关于这个类的描述,类的作用,类的构造函数;
    以及类属性的描述
    Attributes:
        count:写这个属性的含义,类型...
    """
    count = 1

    def run(self,distance,step):
        """
        写这个方法的作用效果
        :param distance:代表距离,int类型,是否有默认值...
        :param step: 代表步长,int类型...
        :return: 返回结果的含义,返回的数据类型...
        """
        print("你好")
        return distance / step

help(Person)

2.属性相关补充

 2.1 私有化属性 / 变量 

       私有化属性是指将一些原本公开的属性设置权限, 只能小范围访问(如:只能在类的内部访问), 其他地方访问不了

       其作用主要是为了保护数据的安全性,提高代码的可维护性

    2.1.1 访问权限测试区域划分

        在给出具体私有化属性之前,我们先界定一下各个访问区域的位置

       通常,我们分为 类的内部、子类内部、模块内部的其他位置、模块外部(跨模块)四个区域

访问权限测试区域划分

    2.1.2 三种属性类型

属性类型定义方式备注
公有属性  x

   变量名 = xxx 

(与常规属性定义一样)

受保护属性  _y _ 变量名 = xxx              一个下划线
私有属性  __z__ 变量名 = xxx             两个下划线

必须在类的内部定义才有效,在实例等定义无效

class Animal:
    x = 100  # 公有属性
    _y = 200 # 受保护属性
    __z = 300 # 私有属性
    pass

print(Animal.x)
print(Animal._y)
print(Animal.__z)

    2.1.3 三种属性类型的访问权限

       首先在某个类中定义一个属性,然后测试在不同区域的访问权限

访问区域公有属性受保护属性私有属性
类的内部
子类内部×
模块内其他位置(但会提醒)×

模块外部

(跨模块)

√(两种方式)

import形式导入
from 模块 import * 形式导入

√(但会提醒)

import形式导入

第二种方式需要先写

__all__ = ["变量"]

同受保护属性

   2.1.4 私有属性的实现机制及应用

        Python并没有真正的私有化支持,但是, 可以使用下划线完成伪私有的效果

  • 具体实现机制:名字重整 

       使用__x,解释器会自动帮我们冲改成另一个名称:_ 类名 __x

       所以再次访问时,会访问不到 __x;如果想访问,需要访问 _ 类名 __x

  • 应用场景:数据保护、数据过滤
class Person:
    """
    这个类的好处是:会默认年龄为18,设定age为私有属性,对数据进行了保护
    同时又可以通过两个函数在实例中对age进行修改和访问
    """
    def __init__(self):
        """
        __init__主要作用:当我们创建好一个实例化对象之后,会自动调用这个方法,来初始化这个对象
        好处:如果是在类中定义,则在每个实例中都不能修改,这样定义,则可以修改
        """
        self.__age = 18

    def setAge(self, value):  # 用来修改年龄
        self.__age = value

    def getAge(self):  # 用来获取年龄
        return self.__age


p1 = Person()
p1.setAge(20)
print(p1.getAge())

p2 = Person()
print(p2.getAge())

    2.1.5 变量添加下划线的其他补充

  • xx_   :"变量名_"  这个格式是为了与系统属性作区分
  • __xx__:两端__  一般为系统内置属性或方法, 所以以后命名注意避免

 2.2 只读属性 

  只读属性是指只能读取、不能写入的(实例)属性,例如:电脑的网速,网络状态

    2.2.1 实现方式一:私有化 + 部分公开

class Person:
    def __init__(self):
        self.__age = 18  # 私有化
    def getAge(self):  # 用来公开:读取
        return self.__age

p1 = Person()
print(p1.getAge())
  • 问题:1)和传统直接调用函数名读取的方式不一致,读取的方式发生了变化                 

                   2)当我们直接调用函数名读取时,不会报错,而是会新增一个属性

  • 优化:使用@property装饰器装饰函数

       property的作用:可以将属性的 删 改 查 这三个操作关联到不同的方法里

class Person(object):  #,如果要设置只读属性,应先继承object类
    def __init__(self):
        self.__age = 18  # 私有化
    
    #这里的作用是,可以以使用属性的方式,来读取这个方法
    @property
    def age(self):  # 用来公开:读取
        return self.__age

p1 = Person()
print(p1.age)
p1.age = 20

     

    2.2.2 经典类和新式类以及property的应用 

  • 经典类:没有继承object类     Python2.x版本定义一个类时, 默认不继承(object)
  • 新式类:继承了object类         Python3.x版本定义一个类时, 默认继承(object)

  • property在新式类中,可以管理一个属性的删改查操作;但在经典类中只能管理这个操作
#在新式类中的使用案例

class Person: #默认继承object
    def __init__(self):
        self.__age = 18  # 私有化
    #这个三个装饰器的作用是,可以以使用属性的方式,来使用这个方法
    @property  #读取 
    def age(self):  # 用来公开:读取
        return self.__age

    @age.setter #修改
    def age(self,value):
        self.__age = value

    @age.deleter #删除
    def age(self):
        del self.__age

p1 = Person()
print(p1.age)
p1.age = 20
print(p1.__dict__)
del p1.age
print(p1.__dict__)

    2.2.3 实现方式二:借助系统内置的方法__setattr__进行拦截

       因为方式一中,是通过伪私有的方式进行私有化属性,我们依然可以通过 _ 类名 __x 的方式访问属性,所以这种方法存在一定的风险

class Person:
    def __setattr__(self, key, value):
        """
        当我么通过 实例.属性 = 值,给实例增加或修改属性时,都会调用这个方法
        在这个方法内部,才会真正的把这个属性以及对应的数据,存储到__dict__字典中
        """
        print(key, value)

        # 1. 判定, key, 是否是我们要设置的只读属性的名称
        if key == "age" and key in self.__dict__.keys():
            print("这个属性是只读属性, 不能设置数据")
        # 2. 如果说不是, 只读属性的名称, 真正的给它添加到这个实例里面去
        else:
            # self.key = value
            self.__dict__[key] = value

p1 = Person()
p1.age = 18
# p1.name = "sz"
# print(p1.age)
print(p1.age)

p1.age = 999
print(p1.age)

print(p1.__dict__)

 2.3 内置特殊属性

内置属性作用备注
__dict__查看类 / 对象的属性类属性
__bases__ 类的所有父类构成元组
__doc__ 类的文档字符串
__name__类名
__module__类定义所在的模块
__class__实例对应的类实例(对象)属性

3.方法相关补充

 3.1 私有化方法

     类似于私有化属性,私有化方法是指将一些原本公开的方法设置权限, 只能小范围访问

  • 语法:def  __方法():                         两个下划线
                              pass

     这个方法原理与私有化属性一样,也是名字重制,要想调用需要输入 "_类名__方法名" 

 3.2 内置特殊方法(了解即可)

      分为生命周期方法(下一章讲)和其他内置方法

内置方法作用格式触发方式
__str__直接输出return后面的描述信息,面向用户,方便阅读

def  __str__(self):
    return "描述信息"

print(实例)或

str(实例)

__repr__直接输出return后面的描述信息,面向开发人员,方便维护

def  __repr__(self):
    return "描述信息"

repr(实例) 
__call__使得“对象”具备当做函数,来调用的能力,调用__call__ 方法下我们定义的内容

def  __call__(self):

    xxxx调用内容

对象名()

(不需要用.__call__)

__setitem__      增

__getitem__      查

__delitem__      删

可以对一个实例对象像字典一样进行索引操作

def __setitem__(self, key, value):

另外两个同理

p["xxx"] = "xx"

p["xxx"]

del p["xxx"]

__iter__    优先级高__getitem__   ...低

可以让我们自己创建的对象使用for in 进行遍历,并返回方法对应的数据

for in 遍历
__next__

让对象可以使用next函数进行访问
    

next(对象)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值