首先,什么是魔法方法呢?在python中方法名如果是__xxxx__()的,那么就有特殊的功能,因此叫做“魔法”方法。

__ init__()方法

  • 当一个实例被创建的时候调用的初始化方法,在创建对象时默认调用。
  • __ init __()方法中默认有一个参数名字为self,如果在创建对象时传递了2个参数,那么__init __()方法除了self作为第一个形参外还需要2个形参,例如__init __(self,x,y)。

之前我们是这样给对象添加属性的:

class Student:
pass stu1 = Student() stu1.name = "张三"
stu1.age = 18

现在我们利用__init__()方法简化代码

class Student:
def __init__(self, name, age):
self.name = name
self.age = age stu1 = Student("张三", 18)

是不是代码看起来简洁多了呢

__str __()方法

  • 一般用于说明对象,或者自己定义一个想要输出的结果。
  • 当调用str()时会调用__str __(),即该对象被强制转换成字符串类型。
  • 当使用print()输出该对象时也会调用__str __()方法,只要自己定义了__str __()方法,那么就会打印这个方法中return中的数据。

没有定义__str __()方法时:

class Student:
def __init__(self, name, age):
self.name = name
self.age = age stu1 = Student("张三", 18)
print(stu1) s = str(stu1)
print(s) """
输出结果:
<__main__.Student object at 0x03C3BCD0>
<__main__.Student object at 0x03C3BCD0>
"""

没有定义__str __()方法时,它默认返回该对象的内存地址。

定义了__str __()方法是这样的:

class Student:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return "姓名:%s\t年龄:%d"%(self.name, self.age) stu1 = Student("张三", 18)
print(stu1) s = str(stu1)
print(s) """
输出结果:
姓名:张三 年龄:18
姓名:张三 年龄:18
"""

__del __()方法

当删除一个对象时,python解释器会默认调用一个方法,这个方法为__del__()方法。

首先应该先了解一个概念,那就是对象的引用个数。我们需要sys模块中的getrefcount()用来测量一个对象的引用个数,返回值=实际的引用个数+1。若返回2则说明该对象的实际引用个数为1,此时有1个变量引用了该对象。

import sys
class A:
pass
a = A()
# 现在只有变量a引用了A类创建的对象
print(sys.getrefcount(a))
"""
输出结果:
2
"""
# 那么现在再创建一个变量b,也引用a所引用的对象,那么它的引用个数就会加1,实际引用个数变成2.
b = a
print(sys.getrefcount(a))
"""
输出结果:
3
"""

当python解释器检测到,这个对象的实际引用个数为0时,就会删除这个对象,此时也就会相应的调用__del __()方法。还有一种情况就是该程序已经全部执行完了,那么相应的内存会被释放掉,它也会执行__del __()方法。

这是程序正常执行完的情况:

import sys
class A:
def __del__(self):
print("该对象被销毁")
a = A()
"""
输出结果:
该对象被销毁
"""

还有一种是手动删除变量引用的情况:

import sys
class A:
def __del__(self):
print("该对象被销毁")
a = A() # 此时实际引用个数为1
b = a # 此时实际引用个数为2 print("删除了变量a")
del a # 删除变量a,此时实际引用个数为1 print("删除了变量b")
del b # 删除变量b,此时实际引用个数为0,python解释器就会删除该对象,即调用__del __()方法
print("程序结束")
"""
输出结果:
删除了变量a
删除了变量b
该对象被销毁
程序结束
"""

__new __()方法

  • __new __也是类在创建实例时调用的方法,它比__init __调用的时间还早。
  • __new __至少要有一个参数cls,代表要实例化的类,此参数在实例化时由python解释器自动提供。
  • __new __必须要有返回值,返回实例化出来的实例,这点在自己实现__new__时要特别注意,可以return父类__new__出来的实例,或者直接是object的__new__出来的实例。在Python3中每个类都默认继承的object父类。
  • __init__有一个参数self,就是这个__new__返回的实例,__init__在__new__的基础上可以完成一些其它初始化的动作,__init__不需要返回值
class A:
def __init__(self):
print("调用了init方法") def __new__(cls):
print("调用了new方法")
return super().__new__(cls)
a = A() """
输出结果:
调用了new方法
调用了init方法
"""

拓展:可以通过重写__new __方法,实现一个单例模式

代码如下:

class A:
# 定义一个私有的类属性,用于存储实例化出来的对象
_isinstance = None def __new__(cls):
print("调用了new方法")
# 判断如果_isinstance为None,则创建一个实例,否则直接返回_isinstance
if not cls._isinstance:
cls._isinstance = super().__new__(cls)
return cls._isinstance print(id(A))
print(id(A))
print(id(A))
print(id(A))
"""
输出结果:
19888488
19888488
19888488
19888488
"""

__slots __属性

我们都知道python是一门动态语言,可以在程序运行的过程中添加属性。如果我们想要限制实例的属性该怎么办?例如,只允许对Person实例添加name和age属性。

为了达到限制的⽬的,Python允许在定义class的时候,定义⼀个特殊的 __slots__变量,来限制该class实例能添加的属性:

class Person(object):
__slots__ = ("name", "age")
P = Person()
P.name = "⽼王"
P.age = 20
P.score = 100 """
输出结果:
Traceback (most recent call last):
File "<input>", line 6, in <module>
AttributeError: 'Person' object has no attribute 'score'
"""

注意:使⽤__slots__要注意,__slots__定义的属性仅对当前类实例起作⽤,对 继承的⼦类是不起作⽤的。

python中几个常见的魔法方法的更多相关文章

  1. python中的魔术属性与魔法方法

    1.魔法属性 · 1.1__doc__魔法属性  表示类的描述信息 class Fo: """ 这是今天第一个魔术属性__doc__""" ...

  2. 面向对象相关概念与在python中的面向对象知识(魔法方法+反射+元类+鸭子类型)

    面向对象知识 封装 封装的原理是,其成员变量代表对象的属性,方法代表这个对象的动作真正的封装是,经过深入的思考,做出良好的抽象(设计属性时用到),给出“完整且最小”的接口,并使得内部细节可以对外透明( ...

  3. Python中执行系统命令常见的几种方法--转载

    Python中执行系统命令常见的几种方法 Python中执行系统命令常见的几种方法有: (1)os.system # 仅仅在一个子终端运行系统命令,而不能获取命令执行后的返回信息 # 如果再命令行下执 ...

  4. python中常用的九种预处理方法

    本文总结的是我们大家在python中常见的数据预处理方法,以下通过sklearn的preprocessing模块来介绍; 1. 标准化(Standardization or Mean Removal ...

  5. Python中异步协程的使用方法介绍

    1. 前言 在执行一些 IO 密集型任务的时候,程序常常会因为等待 IO 而阻塞.比如在网络爬虫中,如果我们使用 requests 库来进行请求的话,如果网站响应速度过慢,程序一直在等待网站响应,最后 ...

  6. 举例详解Python中的split()函数的使用方法

    这篇文章主要介绍了举例详解Python中的split()函数的使用方法,split()函数的使用是Python学习当中的基础知识,通常用于将字符串切片并转换为列表,需要的朋友可以参考下   函数:sp ...

  7. Python中os和shutil模块实用方法集…

    Python中os和shutil模块实用方法集锦 类型:转载 时间:2014-05-13 这篇文章主要介绍了Python中os和shutil模块实用方法集锦,需要的朋友可以参考下 复制代码代码如下: ...

  8. Python中os和shutil模块实用方法集锦

    Python中os和shutil模块实用方法集锦 类型:转载 时间:2014-05-13 这篇文章主要介绍了Python中os和shutil模块实用方法集锦,需要的朋友可以参考下 复制代码代码如下: ...

  9. Python中的str与unicode处理方法

    Python中的str与unicode处理方法 2015/03/25 · 基础知识 · 3 评论· Python 分享到:42 原文出处: liuaiqi627 的博客    python2.x中处理 ...

随机推荐

  1. 51 Nod 1086 多重背包问题(单调队列优化)

    1086 背包问题 V2  基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题  收藏  关注 有N种物品,每种物品的数量为C1,C2......Cn.从中任选若干件放 ...

  2. PyQt5 & Qt Designer使用小结

    开始在知乎写文章的原因,主要还是想整理平时的经验,方便自己以后查看,有机会的话大家也可以交流吧. 11月中旬由于项目需要,和另一名实习生负责使用Python开发一个数据分析的小软件. 虽然才开始接触Q ...

  3. idea maven projects 工具栏按钮的作用

    1.Execute Maven Goal  弹出可执行的 Maven 命令的输入框.有些情况下我们需要通过书写某些执行命令来构建项目,就可以通过此按钮 2.Toggle Offline Mode 英文 ...

  4. Spark译文(三)

    Structured Streaming Programming Guide(结构化流编程指南) Overview(概貌) ·Structured Streaming是一种基于Spark SQL引擎的 ...

  5. [LOJ3109][TJOI2019]甲苯先生的线段树:DP

    分析 首先,请允许我 orz HN队长zsy.链接 我们发现树上的链有两种类,一类是直上直下的,一类不是直上直下的(废话).并且,如果我们确定了左侧和右侧的链的长度和整条链上所有节点的编号之和,那么这 ...

  6. Unity3D_(API)场景切换SceneManager

    Unity场景切换SceneManager 官方文档:传送门 静态方法 创建场景 CreateScene Create an empty new Scene at runtime with the g ...

  7. R_Studio读取xls文件

    百度经验 传送门 需要包xlsx 依赖包rjava 需要安装java编译环境 在R Console中执行命令install.packages("rjava"),install.pa ...

  8. [CSP-S模拟测试]:五子棋(模拟)

    题目传送门(内部题122) 输入格式 输入文件第一行为一个正整数$n$,表示双方总共下了多少步棋. 接下来$n$行,输入文件每行两个正整数.第$i$行的两个数$x,y$表示第$i$步的棋子下在了第$x ...

  9. C++入门经典-例5.2-使用指针比较两个数的大小

    1:代码如下: // 5.2.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> using ...

  10. 树莓派安装parrot linux记录

    手头这台树莓派3b安装parrot linux arm遇到了不少问题,写篇博客记录一下. 1.下载和刻录 网址:https://www.parrotsec.org/download-other.php ...