首页 > 编程语言 >python魔法方法

python魔法方法

时间:2023-02-18 00:56:20浏览次数:34  
标签:__ .__ 定义 python self 魔法 other print 方法

python魔法方法

1.基本的魔法方法

(1)__init__方法

用于对实例进行初始化,在实例创建是会自动执行。

class Hello():
    def __init__(self):
        print("Hello World!")
a = Hello()
#Hello World!

如上,无需调用该方法,在创建实例的时候自动执行了该函数。

(2)__new__方法

该方法是类实例化是第一个调用的方法,__new__至少要有一个参数cls,代表要实例化的类,对当前类进行实例化,并返回一个实例给__init__方法进行初始化。

如下:

class A():
    def __init__(self):
        print("A")
    def __new__(cls, *args, **kwargs):
        print("a")
        return object.__new__(cls)
a = A()
#a
#A

可以看到__new__的执行在__init__前。

如果我们写的类没有写__new__方法,python会默认执行父类的__new__方法,父类也没有该方法,那么会一直按此规矩追溯至object__new__方法,因为object是所有类的父类。所以我们写类并用到该方法时

__new__方法还可以返回其他类的实例,这样当前类的实例就无法通过当前类的__init__进行初始化。

因此,执行了__new__,并不一定会进入__init__,只有__new__返回了,当前类cls的实例,当前类的__init__才会进入。

如下:

class A():
    def __init__(self):
        print("A")
    def __new__(cls, *args, **kwargs):
        print("a")
        return object.__new__(cls)
class B():
    def __init__(self):
        print("B")
    def __new__(cls, *args, **kwargs):
        print("b")
        return object.__new__(A)
b = B()
#b

输出结果只有b,说明类B中的__init__方法没有被调用。

实现单例模式

__new__可以用来实现单例模式,单例模式就是一个类只能有一个实例

这里引用一段代码:

class Earth:
    pass


a = Earth()
print(id(a))  # 260728291456
b = Earth()
print(id(b))  # 260728291624

class Earth:
    __instance = None  # 定义一个类属性做判断

    def __new__(cls):
        if cls.__instance is None:
            cls.__instance = object.__new__(cls)
            return cls.__instance
        else:
            return cls.__instance


a = Earth()
print(id(a))  # 512320401648
b = Earth()
print(id(b))  # 512320401648

这里可以看到,第一次实例化a,b他们的地址不一样,说明是两个实例,而重构Earth类后,再次实例化地址相同。

自定义类的实例化

__new__方法主要是当我们继承一些不可变的 class 时(比如int, str, tuple), 提供一个自定义这些类的实例化过程的途径。

class add(int):
    def __new__(cls, integer):
        integer += 1
        return int.__new__(cls, integer)
a = add(1)
print(a)
#2

而如果没有该方法,应该输出的是1,而不是2。

(3)__del__方法

当需要删除对象来释放类所占用的资源的时候,就需要调用析构方法__del__()。我们可以手动销毁释放内存,或由python自动帮我们销毁。

class CLanguage:
    def __init__(self):
        print("调用 __init__() 方法构造对象")
    def __del__(self):
        print("调用__del__() 销毁对象,释放其空间")
clangs = CLanguage()
#调用 __init__() 方法构造对象
#调用__del__() 销毁对象,释放其空间

如果加上:

del clangs

结果与上述相同。

但有时即使我们手动销毁也不会立即释放该实例的内存。

这里引用一段代码:

class CLanguage:
    def __init__(self):
        print("调用 __init__() 方法构造对象")
    def __del__(self):
        print("调用__del__() 销毁对象,释放其空间")
clangs = CLanguage()
#添加一个引用clangs对象的实例对象
cl = clangs
del clangs
print("***********")
#调用 __init__() 方法构造对象
#***********
#调用__del__() 销毁对象,释放其空间

可以看到,我们使用了del但却是再最后输出,没有立即释放内存,这与python的垃圾回收机制有关。

(4)__str__方法和__repr__方法
__str__方法:

当你打印一个对象的时候,触发__str__

当你使用%s格式化的时候,触发__str__

str强转数据类型的时候,触发__str__

__repr__方法:

reprstr的备胎

__str__的时候执行__str__,没有实现__str__的时候,执行__repr__

repr(obj)内置函数对应的结果是__repr__的返回值

当你使用%r格式化的时候 触发__repr__

区别str更加易读,repr更加准确适合调试。

算术运算符

类型工厂函数

指的是“不通过类而是通过函数来创建对象”。在python2.2之前类与类型分开,类是封装起来的属性与方法,类型是如整型、浮点型、字符型。但之后两者统一了int()str()list()就成了类型工厂函数。如下面的例子:

class C:
    pass

print(type(len))  # <class 'builtin_function_or_method'>
print(type(dir))  # <class 'builtin_function_or_method'>
print(type(int))  # <class 'type'>
print(type(list))  # <class 'type'>
print(type(tuple))  # <class 'type'>
print(type(C))  # <class 'type'>

显示结果都为类。

__add__方法和__sub__方法

分别定义加法和减法,也就是当出现实例间的+和·-是,会分别执行这两种魔法方法。

具体用法如下:

class A():
    def __init__(self, n):
        self.n = int(n)

    def __add__(self, other):
        return A(self.n + other.n)

    def __sub__(self, other):
        return A(self.n - other.n)
a = A(1)
b = A(2)
c = a - b
d = a + b
print(c.n, d.n)
#-1 3

这就是给实例的计算提供了方法。

下面有个有趣的例子:

class Int(int):
    def __add__(self, other):
        return int.__sub__(self, other)
    def __sub__(self, other):
        return int.__add__(self, other)
a = Int(3)
b = Int(4)
print(a + b, a - b)
#-1 7

这里我们看到加法与减法颠倒了。

除以上两种,还有其他常见的算术运算符如下:

1.__mul__(self, other)定义乘法的行为:*

2.__truediv__(self, other)定义真除法的行为:/

3.__floordiv__(self, other)定义整数除法的行为://

4.__mod__(self, other) 定义取模算法的行为:%

5.__divmod__(self, other)定义当被 divmod() 调用时的行为,divmod(a, b) 就是把除数和余数运算结果结合起来,返回一个包含商和余数的元组(a // b, a % b).

6.__pow__(self, other[, module])定义当被 power() 调用或 ** 运算时的行为

7.__lshift__(self, other)定义按位左移位的行为:<<

8.__rshift__(self, other)定义按位右移位的行为:>>

9.__and__(self, other)定义按位与操作的行为:&

10.__xor__(self, other)定义按位异或操作的行为:^

11.__or__(self, other)定义按位或操作的行为:|

反算术运算符

与算术运算符一一对应,但是前面多了一个r,当文件左操作不支持相应的操作时被调用。如a+b时,如果a对象的__add__()方法没有实现或者不支持相应的操作,那么 Python 就会调用b__radd__()方法。

1.__radd__(self, other)定义加法的行为:+

2.__rsub__(self, other)定义减法的行为:-

3.__rmul__(self, other)定义乘法的行为:*

4.__rtruediv__(self, other)定义真除法的行为:/

5.__rfloordiv__(self, other)定义整数除法的行为://

6.__rmod__(self, other) 定义取模算法的行为:%

7.__rdivmod__(self, other)定义当被 divmod() 调用时的行为

8.__rpow__(self, other[, module])定义当被 power() 调用或 ** 运算时的行为

9.__rlshift__(self, other)定义按位左移位的行为:<<

10.__rrshift__(self, other)定义按位右移位的行为:>>

11.__rand__(self, other)定义按位与操作的行为:&

12.__rxor__(self, other)定义按位异或操作的行为:^

13.__ror__(self, other)定义按位或操作的行为:|

增量赋值运算符

1.__iadd__(self, other)定义赋值加法的行为:+=

2.__isub__(self, other)定义赋值减法的行为:-=

3.__imul__(self, other)定义赋值乘法的行为:*=

4.__itruediv__(self, other)定义赋值真除法的行为:/=

5.__ifloordiv__(self, other)定义赋值整数除法的行为://=

6.__imod__(self, other)定义赋值取模算法的行为:%=

7.__ipow__(self, other[, modulo])定义赋值幂运算的行为:**=

8.__ilshift__(self, other)定义赋值按位左移位的行为:<<=

9.__irshift__(self, other)定义赋值按位右移位的行为:>>=

10.__iand__(self, other)定义赋值按位与操作的行为:&=

11.__ixor__(self, other)定义赋值按位异或操作的行为:^=

12.__ior__(self, other)定义赋值按位或操作的行为:|=

一元运算符

1.__neg__(self)定义正号的行为:+x

2.__pos__(self)定义负号的行为:-x

3.__abs__(self)定义当被abs()调用时的行为

4.__invert__(self)定义按位求反的行为:~x

属性访问

1.__getattr__(self, name): 定义当用户试图获取一个不存在的属性时的行为。

2.__getattribute__(self, name):定义当该类的属性被访问时的行为(先调用该方法,查看是否存在该属性,若不存在,接着去调用__getattr__)。

3.__setattr__(self, name, value):定义当一个属性被设置时的行为。

4.__delattr__(self, name):定义当一个属性被删除时的行为。

描述符

1.__get__(self, instance, owner)用于访问属性,它返回属性的值。

2.__set__(self, instance, value)将在属性分配操作中调用,不返回任何内容。

3.__del__(self, instance)控制删除操作,不返回任何内容。

定制序列

1,__len__(self)定义当被len()调用时的行为(返回容器中元素的个数)。

2.__getitem__(self, key)定义获取容器中元素的行为,相当于self[key]

3.__setitem__(self, key, value)定义设置容器中指定元素的行为,相当于self[key] = value

4.__delitem__(self, key)定义删除容器中指定元素的行为,相当于del self[key]

迭代器

特点
  • 迭代是 Python 最强大的功能之一,是访问集合元素的一种方式。
  • 迭代器是一个可以记住遍历的位置的对象。
  • 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。
  • 迭代器只能往前不会后退。
  • 字符串,列表或元组对象都可用于创建迭代器:
方法

迭代器有两个方法

  • iter(object) 函数用来生成迭代器。
  • next(iterator[, default]) 返回迭代器的下一个项目。

标签:__,.__,定义,python,self,魔法,other,print,方法
From: https://www.cnblogs.com/102204216zxf/p/17131846.html

相关文章

  • Python 连接数据源与邮件功能(九)
    目录一、概述二、Python连接数据源1)PythonMySQL基础操作1、部署MySQL2、MySQLConnector库【1】安装mysql-connector-python库【2】连接MySQL【3】增加数据【4】查......
  • Python实现动态码
    通过Python的MyQR模块来实现动态码,具体实现代码如下:#-*-coding:utf-8-*-fromMyQRimportmyqr#此处注意大小写#使用前需要先安装myqr模块,终端里运行:pipinstall......
  • 【视频】风险价值VaR原理与Python蒙特卡罗Monte Carlo模拟计算投资组合实例|附代码数
    原文链接:http://tecdat.cn/?p=22862 最近我们被客户要求撰写关于风险价值VaR的研究报告,包括一些图形和统计输出。风险价值(VaR)是一种统计数据,用于量化公司、投资组......
  • Linux - curl 使用方法
    curl是强大的开源的数据传输工具,它支持很多协议,其中使用最多的是HTTP/HTTPS协议。curl使用libcurl库,很多编程语音都可以使用这个库1、curl基本使用curlblog.ling218......
  • python学习——【第十弹】
    前言上篇文章​​python学习——【第九弹】​​中我们学习了python面向对象的三大特征:封装,继承,多态。这篇文章也是有关类的一些特殊的使用方法和属性。特殊方法Python类中,......
  • Python爬虫-第五章-2-爬取某网站图库
    技术点  1.requests  2.beautifulSoupps:程序可扩展  1.比如翻页下载  2.下拉加载更多可以用selenium  3.多线程或者异步协程提升下载效率 ......
  • 用Python做一个小说下载器,从获取数据到编写GUI界面
    对于广大书虫而言,没有小说看是最痛苦的,你身边有这样的人吗?今天咱们分享一个小说下载器代码,打包成exe后,发给你的小伙伴也能直接使用…思路流程什么是爬虫?......
  • python项目中的“填坑”记录
    基础Python是动态类型的语言,Python中任何事物皆对象,如变量、数据结构、函数、类、模块等等,在创建一个对象的时候就会占用内存,Python中对象和引用是分离。Python的内存管理......
  • 【已解决】com.alibaba.fastjson.JSONException: expect ':' at 0 解决方法【一行就解
    报错原因是把List<Map<String,Object>>直接转json,其中格式不对就报错了。List<Map<String,Object>>listinfo=repository.getxxxx(xx,xx,xx);当for中使用:JSONObjectobj=......
  • python-json解析
    json函数:json.dumps:将python对象解析成jsonjson.loads:将已编码的JSON字符串解码为Python对象json.dumps使用将数组转为json格式数据importjsonif__name__=='__main_......