百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术资源 > 正文

python中self有哪些赋值方式(python中self的用法)

off999 2024-11-17 14:33 30 浏览 0 评论

这周比较忙,趁周末有空更新一篇文章,本文主要讲解类中实例赋值涉及的几种场景。

方法一;赋值即定义
场景:常用方式
样例:self.name = laokoo

方法二;setattr函数赋值
场景:使用字符串的方式操作实例的属性
样例: setattr(self,'name','laokoo')

方法三;实例字典赋值
场景:非标方式,本质上实例就是通过这种方式储存属性的
样例:self.__dict__[name] = 'laokoo'

方法四;类中实现__setattr__魔术方法
场景:=号赋值的方式,setattr函数的赋值本质上都是调用__setattr__魔术方法进行赋值。
    __setattr__魔术方法中调用基类的该方法可以实现self属性的赋值
    __setattr__魔术方法中使用实例字典赋值的方式可以实现self属性赋值
    __setattr__魔术方法中如果使用=号赋值或者setattr函数会引起无限递归
样例:详见下方代码

方法五;类属性是另外一个类的实例,该类属性也是实例的属性
场景:实例访问类属性会触发描述器调用装饰类__get__方法的返回值
    实例通过=号赋值会触发描述器调用装饰类的__set__方法进行属性设置
样例:详见下方代码

方法六,类中实现__slots__属性
场景:类中实现该方法后会禁用掉实例的字典,实例的属性全部通过类属性进行储存。
    该属性主要针对实例属性过多,内存资源不足,实例属性较为简单的场景
    __slots__不支持动态添加属性,__slots__不支持类继承
建议:可以使用tracemalloc模块测试元组和字典内存空间占用效果
样例:详见下方代码

备注:方法六中我打印了实例属性"member 'name' of 'Person' objects"
    类型是"class 'member_descriptor'"。小弟其实不太明白__slots__
    后端的实现原理,例如__slots__是用什么数据类型存放数据,member_descriptor
    类中不同实例同一个属性是如何存储的。

惯例先上汇总说明,后上代码参考。为了方便大家测试,我将测试区代码封装成了多个小块,大家在测试时根据场景不同区分调用即可。

此外本次测试中描述器方法,反射方法,slots方法可能会相互干扰,所以大家如果有测试需求请测试时关闭掉存在干扰的选项(存在干扰的我已经在文中进行了说明),另外大家如果不太明白描述器原理也可以查看我之前整理的一篇关于描述器的说明。

class Face:

    def __get__(self, instance, owner):
        print('in get ~~~')
        return self

    # 装饰类必须实现set魔术方法才能影响功能类的赋值语句
    def __set__(self, instance, value):
        print('in set ~~~~')
        self.data = value

    def __repr__(self):
        return '<face instance>'


class Person:
    face = Face()

    # #最后测试再开启,slots会禁用掉实例的字典,所以代码中只要使用到实例__dict__的部分都会报错。测试该功能前请关闭dict使用项
    # __slots__ = ['name','age']

    def __init__(self, name):
        print('in init ~~~~')
        self.name = name
        # 观察face的值,观察实例的字典
        self.face = 'myface'

    # 第一阶段我们不设置该魔术方法,第二阶段开启该魔术方法
    def __setattr__(self, key, value):
        print('{} {} in setattr ~~~'.format(key, value))
        print(self.__dict__)
        # 测试一,调用基类方法观察效果
        super().__setattr__(key, value)
        # 测试二,直接使用实例字典赋值观察效果
        # self.__dict__[key] = value
        # 测试三,直接使用实例赋值观察效果
        # self.key = value
        # 测试四,使用setattr函数赋值观察效果
        # setattr(self,key,value)
        print(self.__dict__)


def test_show(user_input: int):
    """为了方便观察,我将一个测试场景进行了打印区分"""
    if user_input == 1:
        """第一阶段使用方式一进行测试
        测试方法:通过=的方式直接赋值
        观察结果:name的值,实例的字典"""
        laokoo = Person('laokoo')
        print(laokoo.name)
        laokoo.name = 'kabu'
        print(laokoo.__dict__)
        print(laokoo.name)
    elif user_input == 2:
        """第一阶段使用方式二进行测试
        测试方法:setattr()函数赋值
        观察结果:name的值,实例的字典"""
        laokoo = Person('laokoo')
        print(laokoo.name)
        setattr(laokoo, 'name', 'kabu')
        print(laokoo.__dict__)
        print(laokoo.name)
    elif user_input == 3:
        """第一阶段使用第三种方式测试
        测试方法:使用实例字典直接赋值(非标)
        观察结果:name的值,实例字典"""
        laokoo = Person('laokoo')
        print(laokoo.name)
        laokoo.__dict__['name'] = 'kabu'
        print(laokoo.__dict__)
        print(laokoo.name)
    elif user_input == 4:
        """第二阶段使用第四种方式测试,这里的知识点比较多
        测试方式:直接赋值,setattr函数赋值,这两种方法在__setattr__中测试
        观察结果:name的值,__setattr__方法执行,实例字典"""
        laokoo = Person('laokoo')
        """观察实例的初始化逻辑,先调用init,然后遇见赋值语句,直接调用__setattr__魔术方法,然后将key,value传入
        因为我们的赋值动作最终实现效果是往实例的字典添加键值对,所以该魔术方法最终也会执行该操作"""
        print(laokoo.name)
    elif user_input == 5:
        """第三阶段使用第五种测试,这里会用到描述器,建议关闭掉功能类的setattr方法,不然显示内容太多
        测试方法:直接赋值,setattr函数赋值
        观察结果:face的值"""
        laokoo = Person('laokoo')
        print(laokoo.face)
        # 观察data是否由值输出
        print(laokoo.face.data)
    elif user_input == 6:
        """第四阶段使用第六种测试,这里会用到__slots__
        """
        laokoo = Person('laokoo')
        setattr(laokoo,'age',18)
        # setattr(laokoo,'x','xx')
        #实例字典会被禁用,会使用类字典储存属性值
        # print(laokoo.__dict__)
        #name字段对应的值是'name': <member 'name' of 'Person' objects>(类型<class 'member_descriptor'>),
        print(Person.__dict__)
        #开启__slot__后name才会切换到类属性
        # print(type(Person.name))

相关推荐

Python Flask 容器化应用链路可观测

简介Flask是一个基于Python的轻量级Web应用框架,因其简洁灵活而被称为“微框架”。它提供了Web开发所需的核心功能,如请求处理、路由管理等,但不会强制开发者使用特定的工具或库。...

Python GUI应用开发快速入门(python开发软件教程)

一、GUI开发基础1.主流GUI框架对比表1PythonGUI框架比较框架特点适用场景学习曲线Tkinter内置库,简单小型应用,快速原型平缓PyQt功能强大,商用许可专业级桌面应用陡峭PySi...

【MCP实战】Python构建MCP应用全攻略:从入门到实战!

实战揭秘:Python Toga 打造跨平台 GUI 应用的神奇之旅

在Python的世界里,GUI(图形用户界面)开发工具众多,但要找到一款真正跨平台、易于使用且功能强大的工具并不容易。今天,我们就来深入探讨一下Toga——一款Python原生、操作系统原...

python应用目录规划(python的目录)

Python大型应用目录结构规划(企业级最佳实践)核心原则模块化:按业务功能拆分,高内聚低耦合可扩展性:支持插件机制和动态加载环境隔离:清晰区分开发/测试/生产环境自动化:内置标准化的构建测试部署流...

Python图形化应用开发框架:PyQt开发简介

PyQt概述定义:PyQt是Python绑定Qt框架的工具集,用于开发跨平台GUI应用程序原理:通过Qt的C++库提供底层功能,PyQt使用SIP工具生成Python绑定特点:支持Windows/ma...

[python] 基于PyOD库实现数据异常检测

PyOD是一个全面且易于使用的Python库,专门用于检测多变量数据中的异常点或离群点。异常点是指那些与大多数数据点显著不同的数据,它们可能表示错误、噪声或潜在的有趣现象。无论是处理小规模项目还是大型...

Python、Selenium 和 Allure 进行 UI 自动化测试的简单示例脚本

环境准备确保你已经安装了以下库:SeleniumAllurepytest你可以使用以下命令安装所需库:pipinstallseleniumallure-pytestpytest示例代码下面的代...

LabVIEW 与 Python 融合:打造强大测试系统的利器

在现代测试系统开发领域,LabVIEW和Python各自凭借独特优势占据重要地位。LabVIEW以图形化编程、仪器控制和实时系统开发能力见长;Python则凭借丰富的库资源、简洁语法和强大数...

软件测试进阶之自动化测试——python+appium实例

扼要:1、了解python+appium进行APP的自动化测试实例;2、能根据实例进行实训操作;本课程主要讲述用python+appium对APP进行UI自动化测试的例子。appium支持Androi...

Python openpyxl:读写样式Excel一条龙,测试报表必备!

无论你是测试工程师、数据分析师,还是想批量导出Excel的自动化工作者,只需一个库openpyxl,即可高效搞定Excel的各种需求!为什么选择openpyxl?支持.xlsx格式...

Python + Pytest 测试框架——数据驱动

引言前面已经和大家介绍过Unittest测试框架的数据驱动框架DDT,以及其实现原理。今天和大家分享的是Pytest测试框架的数据驱动,Pytest测试框架的数据驱动是由pytest自...

这款开源测试神器,圆了我玩游戏不用动手的梦想

作者:HelloGitHub-Anthony一天我在公司用手机看游戏直播,同事问我在玩什么游戏?我和他说在看直播,他恍然大悟:原来如此,我还纳闷你玩游戏,咋不用动手呢。。。。一语惊醒梦中人:玩游戏不用...

Python单元测试框架对比(pycharm 单元测试)

一、核心框架对比特性unittest(标准库)pytest(主流第三方)nose2(unittest扩展)doctest(文档测试)安装Python标准库pipinstallpytestp...

利用机器学习,进行人体33个2D姿态检测与评估

前几期的文章,我们分享了人脸468点检测与人手28点检测的代码实现过程,本期我们进行人体姿态的检测与评估通过视频进行人体姿势估计在各种应用中起着至关重要的作用,例如量化体育锻炼,手语识别和全身手势控制...

取消回复欢迎 发表评论: