python 魔法函数学习

这篇具有很好参考价值的文章主要介绍了python 魔法函数学习。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一:魔法函数特点

1、 魔法函数也就是魔术方法,是python定义的方法,不属于某个类,不是因为继承而拥有的方法,每一个类都可以添加魔法函数,以双下划线开头和双下划线结尾,例如__getitem__,python内置的魔法函数有很多
2、魔术方法的名称不能随意更改
3、魔术方法对当前这个类进行了功能拓展
4、魔术方法可以更改当前这个类的类型

二:部分魔法函数案例讲解

案例1 __getitem__魔法函数:

例如下面的的类,仅在构造函数里面传入一个列表,如果想对这个实例化对象循环读取值是会报错的

class Student:
    def __init__(self,student_list):
        self.student_list = student_list
        
if __name__ == '__main__':
    student = Student(["marry","clain","lili"])
    for item in student:
        print(item)

运行结果如下:

Traceback (most recent call last):
  File "F:/myfile/python/code/python3进阶/chapter06/getattr.py", line 32, in <module>
    for item in student:
TypeError: 'Student' object is not iterable

提示Student不是一个可迭代的对象,那如何让他变成可迭代呢,getitem这个魔法函数就可以实现,修改如下:

class Student:
    def __init__(self,student_list):
        self.student_list = student_list
    
    #魔法函数
    def __getitem__(self, item):
        return self.student_list[item]
if __name__ == '__main__':
    student = Student(["marry","clain","lili"])
    for item in student:
        print(item)

运行结果:

marry
clain
lili

现在Student 就是一个可迭代的对象了。当执行for循环的时候就会自动调用__getitem__这个魔法函数,getitem中的参数item 就是索引,从0开始,直到python运行抛出异常,自动结束for循环。

案例2 __len__魔法函数:

class Student:
    def __init__(self,student_list):
        self.student_list = student_list
    
    #魔法函数
    def __getitem__(self, item):
        return self.student_list[item]
if __name__ == '__main__':
    student = Student(["marry","clain","lili"])
    #student现在是可迭代的,就可以进行切片,切片之后变成一个序列
    student_1 = student[:2]
    print(type(student_1))
    print(len(student_1))

输出结果:

<class 'list'>
2

可以看到Student现在可迭代,可以对实例进行切片,切片后变成一个序列。对这个序列输出长度是可以的,如果我现在想对这个实例的对象求长度呢,可以看下面的代码

class Student:
    def __init__(self,student_list):
        self.student_list = student_list
    
    #魔法函数
    def __getitem__(self, item):
        return self.student_list[item]
if __name__ == '__main__':
    student = Student(["marry","clain","lili"])
    print(len(student))

运行结果:

Traceback (most recent call last):
  File "F:/myfile/python/code/python3进阶/chapter06/getattr.py", line 44, in <module>
    print(len(student))
TypeError: object of type 'Student' has no len()

提示对象Student没有len()的方法。那我们来添加__len__的魔法函数看下

class Student:
    def __init__(self,student_list):
        self.student_list = student_list
    
    #魔法函数
    def __getitem__(self, item):
        return self.student_list[item]
        
    #让当前的类变成一个序列类型
    def __len__(self):
        return len(self.student_list)                                                                                                                                                                                                     
        
if __name__ == '__main__':
    student = Student(["marry","clain","lili"])
    print(len(student))

运行结果:

3

添加了__len__的魔法函数后就可以使用len获取实例对象里面列表的长度了,让当前的类变成一个序列类型

案例3__str__ 魔法函数

class Student:
    def __init__(self,student_list):
        self.student_list = student_list

    def __getitem__(self, item):
        return self.student_list[item]
if __name__ == '__main__':
    student = Student(["marry","clain","lili"])
    print(student)

输出结果:

<__main__.Student object at 0x0000015D3F49A940>

比如上面打印出来的对象地址,我们想要打印的是实例化对象里面的值,输出"marry",“clain”,“lili”,这个时候就需要__str__魔法函数来格式化输出了

class Student:
    def __init__(self,student_list):
        self.student_list = student_list

    def __getitem__(self, item):
        return self.student_list[item]
    #格式化输出
    def __str__(self):
        return ','.join(self.student_list)         

if __name__ == '__main__':
    student = Student(["marry","clain","lili"])
    #当使用print进行实例化对象打印的时候,自动调用__str__方法
    print(student)

在看输出结果:

marry,clain,lili

案例4__getattr__和__getattribute__ 魔法函数

from datetime import date
class User:
    def __init__(self,name,birthday):
        self.name = name
        self.birthday = birthday

if __name__ == '__main__':
    user = User("黛玉",date(year=1982,month=2,day=21))
    print(user.age)

如果是上面的代码,调用了不存在的属性age,会报错
输出结果如下:

Traceback (most recent call last):
  File "F:/myfile/python/code/python3进阶/chapter06/getattr.py", line 14, in <module>
    print(user.age)
AttributeError: 'User' object has no attribute 'age'

当我们加上__getattr__魔法函数的时候,就不会报错了。

from datetime import date

class User:
    def __init__(self,name,birthday):
        self.name = name
        self.birthday = birthday

    def __getattr__(self, item):
        return "no shuch attribute"

if __name__ == '__main__':
    user = User("黛玉",date(year=1982,month=2,day=21))
    print(user.age)

输出结果如下:

no shuch attribute

Process finished with exit code 0

当调用到对象的属性值,并且这个属性值不存在的时候,就会自动调用__getattr__这个魔法函数,在这个魔法函数里面我们可以实现不存在的属性值的情况

在来看下__getattribute__ 魔法函数

from datetime import date
class User:
    def __init__(self,name,birthday):
        self.name = name
        self.birthday = birthday

    def __getattr__(self, item):
        return "no shuch attribute"

    def __getattribute__(self, item):
        return "欢迎进入getattribute"

if __name__ == '__main__':
    user = User("黛玉",date(year=1982,month=2,day=21))
    print(user.test)
    print(user.name)

输出结果:

欢迎进入getattribute
欢迎进入getattribute

Process finished with exit code 0

总结:
_getattr 是在查找不到属性的时候调用
getattribute 是获取属性的入口,不管调用的是什么属性都会进入到这个魔法函数,这个魔法函数不要轻易重写

案例5__enter__ 和__exit__魔法函数

上下文管理协议
在一个类中只要实现了__enter__ 和__exit__这两个魔法函数,就可以使用with
在with 创建类实例的时候会自动调用__enter__魔法函数,在调用实例方法的时候会自动调用__exit__

class Sample:
    def __enter__(self):
        #可以实现获取资源的方法
        print("enter")
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        #可以写释放资源的方法
        print("exit")


    def do_something(self):
        print("do something")


with Sample() as sample:
    sample.do_something()

输出结果:

enter
do something
exit

with 语句还可以通过contextlib来实现相同的效果

import contextlib

@contextlib.contextmanager
def file_open(file_name):
    print("file open")
    yield {}
    print("file end")

with file_open("boy.txt") as f:
    print("file processing")

输出结果:文章来源地址https://www.toymoban.com/news/detail-508902.html

file open
file processing
file end

到了这里,关于python 魔法函数学习的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • vue新学习 02 vue命令v-model,数据代理(作用域和作用域链),事件,监听,条件渲染,计算属性(也就是把操作属性的语句放到vue实例中)

    双向绑定用命令v-model: v-bind的命令是单项去绑定data中的相关属性,此时的data是真正的data,并没有用变量声明的方式去接收vue实例对象,也就是例如用const vm = new Vue({})。而是直接就采用了new Vue({})这样子的形式,(v-bind和v-model在这个例子中都是如此,所以现在并没有数据

    2024年02月15日
    浏览(31)
  • python 魔法函数学习

    1、 魔法函数也就是魔术方法,是python定义的方法,不属于某个类,不是因为继承而拥有的方法,每一个类都可以添加魔法函数,以双下划线开头和双下划线结尾,例如__getitem__,python内置的魔法函数有很多 2、魔术方法的名称不能随意更改 3、魔术方法对当前这个类进行了功

    2024年02月11日
    浏览(28)
  • Python中的魔法函数

    魔法函数(Magic functions),也称为特殊方法(Special methods),是在 Python 中具有特殊名称和双下划线(__)前缀和后缀的特殊函数。 这些魔法函数允许您定义自定义行为,以便在特定的操作中调用。它们可以使您的对象表现得像内置类型一样,并提供了一种自定义类行为的方

    2024年02月07日
    浏览(30)
  • 【Python】Python函数的黑魔法:递归,嵌套函数与装饰器

    欢迎来到CILMY23的博客 本篇主题为: Python函数的黑魔法:递归,嵌套函数与装饰器 个人主页:CILMY23-CSDN博客 系列专栏:Python | C++ | C语言 | 数据结构与算法 感谢观看,支持的可以给个一键三连,点赞关注+收藏。 写在前头: 本期主要补充上篇未完成的内容,(点击链接

    2024年04月25日
    浏览(26)
  • 编程江湖:Python探秘之旅-----函数的魔法(三)

    项目进行到关键阶段,“云悟”,项目经理,强调了代码的模块化和重用性的重要性。她希望团队能够提高工作效率,避免重复劳动。 云悟 :(审视着代码)我们需要使这些代码更加模块化。这样,我们就可以在不同的项目中重用这些功能,而不是每次都从头开始。 龙 :(

    2024年01月25日
    浏览(36)
  • Python中的`__all__`魔法函数使用详解

    Python是一门灵活而强大的编程语言,提供了各种机制来控制模块的导入和访问。其中, __all__ 魔法函数是一种用于限制模块导入的机制,可以明确指定哪些变量、函数或类可以被导入。本文将深入探讨 __all__ 的作用、用法以及示例,以帮助大家更好地理解和使用这一功能。

    2024年04月11日
    浏览(30)
  • 【硬件学习笔记002】光耦也就那么一回事

            光耦一般分为两种:一种为光电晶体管输出光耦(非线性),另一种为逻辑输出光耦(线性)。         逻辑输出光耦的电流传输特性曲线是非线性的,适合于开关信号的传输,不适合于传输模拟量; 光电晶体管输出光耦的电流传输特性是线性的,适合传输模拟量

    2024年02月13日
    浏览(30)
  • jupyter中的魔法函数

    在jupyter中,使用魔法函数可以简单的实现一些单纯python要很麻烦才能实现的功能。 行魔法函数,只对本行代码生效。 Cell魔法函数,在整个Cell中生效,必须放于Cell首行。 列出所有的魔法函数      一些好用的魔法函数: 将 matplotlib 画出的图直接显示在 Notebook 之中 现在的

    2023年04月19日
    浏览(29)
  • c++——重写(覆盖),实际上对应的就是虚函数

    重写 是指派生类中存在重新定义的函数。其函数名,参数列表,返回值类型,所有都必须同基类中被重写的函数一致。只有函数体不同(花括号内),派生类调用时会调用派生类的重写函数,不会调用被重写函数。重写的基类中被重写的函数必须有virtual修饰。

    2024年02月12日
    浏览(29)
  • 反序列化漏洞及PHP魔法函数

    目录 1、漏洞原理 2、序列化(以PHP语言为例) 3、反序列化 4、PHP魔法函数 (1)__wakeup() (2)__destruct() (3)__construct() (4)__toString() (5)__get() (6)__call() PHP反序列化漏洞也叫PHP对象注入,形成的原因是程序未对用户输入的序列化字符串进行检测,导致攻击者可以控制反

    2024年02月04日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包