python魔术方法abstract_Python 进阶之魔术方法

本文介绍了Python中的魔术方法,包括__str__、__repr__、__init__、__new__、数学和比较运算符重载、容器方法、上下文管理、内省以及槽。通过实例展示了如何使用这些魔术方法实现特殊功能,如单例模式、自定义运算符、属性监听等。
摘要由CSDN通过智能技术生成

Python魔术方法

__开头,__结尾的方法就是魔术方法.

1.__str__格式化输出对象

__repr__表示对象本身

class A:

def __str__(self):

return 'This is A'

# 表示对象本身

def __repr__(self):

return "I'm a A"

a = A()

print(a) # This is A

a # I'm a A

2.__init__和 __new__

__init__ 初始化实例,无返回值

__new__创建一个实例,并返回类的实例.

__new__是一个特殊的类方法,不需要使用@classmethod来装饰.

使用__new__单例模式

# 借助__new__方法实现单例模式

class Singleton:

instance = None

def __new__(cls, *args, **kwargs):

# 判断实例对象是否已经存在

if cls.instance is None:

# 说明实例对象不存在.需要创建

cls.instance = super().__new__(Singleton, *args, **kwargs)

return cls.instance

s = Singleton()

s2 = Singleton()

s is s2

out: True

display(id(s), id(s2))

out: 78960288 78960288

3.数学运算、比较运算

运算符重载

+:__add__(value)

-: __sub__(value) substract

*: __mul__(value) mulply

/: __truediv__(value) (Python 3.x), __div__(value) (Python 2.x) divide

//: __floordiv__(value)

%: __mod__(value)

&: __and__(value)

|:__or__(value)

# 自定义字典的加法

class Dict(dict):

# 实现加法

def __add__(self, other):

# 判断other是否是字典.

if isinstance(other, dict):

new_dict = {}

new_dict.update(self)

new_dict.update(other)

return new_dict

else:

raise TypeError('not a dict')

d1 = {1: 11, 2: 22}

d2 = {1: 111, 2: 222, 3:333}

dd1 = Dict(d1)

dd1 + d2

out:{1: 111, 2: 222, 3: 333}

# 定义一个类,长方形 , 让长方形类的实例对象可以实现减法操作.

class Rectangle:

def __init__(self, height, width):

self.height = height

self.width = width

# 实现减法

def __sub__(self, other):

if isinstance(other, Rectangle):

return Rectangle(abs(self.height - other.height), abs(self.width - other.width))

else:

raise TypeError('not a rectangle')

def __repr__(self):

return f''

r1 = Rectangle(1,2)

r2 = Rectangle(1,1)

r1 - r2

out:

比较运算符的重载

==: __eq__(value)

!=: __ne__(value)

>: __gt__(value)

>=: __ge__(value)

<: __lt__>

<=: __le__(value)

# 定一个类实现数学上的无穷大

class Inf:

def __eq__(self, other):

return False

def __ne__(self, other):

return True

def __gt__(self, other):

return True

def __ge__(self, other):

return False

def __lt__(self, other):

return False

def __le__(self, other):

return False

inf = Inf()

inf > 20 ** 10000

out:True

# 练习: 写个长方体, 让长方体的实例对象之间可以比体积大小.

# 优化版本

class Cuboid:

def __init__(self, lenght, width, height):

self.lenght = lenght

self.width = width

self.height = height

@property

def V(self):

return self.lenght * self.width * self.height

def __gt__(self, other):

if isinstance(other, Cuboid):

return self.V > other.V

else:

raise TypeError('not a cuboid')

def __repr__(self):

return f''

c1 = Cuboid(2,3,4)

c2 = Cuboid(1,1,1)

c1 > c2

out:True

sorted([c1,c2]) # 对体积进行排序

out:[, ]

4.容器方法

__len__ -> len

__iter__ -> for

__contains__ -> in

__getitem__ 对 string, bytes, list, tuple, dict 有效

__setitem__ 对 list, dict 有效

__missing__ 对 dict 有效, 字典的预留接口, dict 本身并没有实现

l = [1,2,3]

len(l)

out:3

l.__len__()

out:3

l[0]

out: 1

l.__getitem__(0)

out: 1

l[0] = 8

l

out:[8, 2, 3]

l.__setitem__(0,10)

l

out: [10, 2, 3]

d1 = {1: 111, 2: 222, 3: 333}

d1[0]

out:---------------------------------------------------------------------------

KeyError Traceback (most recent call last)

in ()

----> 1 d1[0]

KeyError: 0

# 让字典的key找不到的时候,不要报错.返回空列表

class Dict(dict):

def __missing__(self, key):

return []

ddd = Dict(d1)

ddd[0]

out: []

5.上下文管理 with:

__enter__进入 with 代码块前的准备操作

__exit__ 退出时的善后操作

文件对象、线程锁、socket 对象 等 都可以使用 with 操作

with 不管with语句块中是否出现异常,资源依然可以被正常的释放.

exceptions = []

class A:

def __enter__(self):

print('enter....')

print(self)

return self

def __exit__(self, Error, error, Exception):

print(Error, error, Exception)

exceptions.append(Error)

exceptions.append(error)

exceptions.append(Exception)

print('exiting....')

with A() as a:

print(a)

print('------------------')

raise TypeError()

out:enter....

------------------

exiting....

---------------------------------------------------------------------------

TypeError Traceback (most recent call last)

in ()

2 print(a)

3 print('------------------')

----> 4 raise TypeError()

5

TypeError:

exceptions

out:[TypeError, TypeError(), ]

Error, error, trace = exceptions

import traceback

traceback.print_exception(Error, error, trace) # 打印出异常

out:Traceback (most recent call last):

File "", line 4, in

raise TypeError()

TypeError

python的内省

setattr() # 设置属性__setattr__()

getattr() # 获取属性__getattribute__

hasattr() # 判断是否有某个属性

class A:

def __init__(self, x, y):

self.x = x

self.y = y

a = A(1,2)

setattr(a, 'z', 3)

a.z

out: 3

a.__setattr__('z', 9)

a.z

out: 9

getattr(a, 'x')

out: 1

a.__getattribute__('x')

out: 1

# __getattr__当__getattribute__找不到属性的时候,会执行__getattr__

# 默认获取不到会报错

getattr(a, 'a', 0)

out: 0

hasattr(a, 'a')

out: False

'a' in a.__dict__

out: False # 没有a.__hasattr__('a')

# 常用于属性监听

class User:

'''TestClass'''

z = [7,8,9]

def __init__(self):

self.money = 10000

self.y = 'abc'

def __setattr__(self, name, value):

if name == 'money' and value < 0:

raise ValueError('money < 0')

print('set %s to %s' % (name, value))

object.__setattr__(self, name, value)

def __getattribute__(self, name):

print('get %s' % name)

return object.__getattribute__(self, name)

def __getattr__(self, name):

print('not has %s' % name)

return -1

def foo(self, x, y):

return x ** y

# 对比

a = User()

# print(User.__dict__)

# print(a.__dict__)

out: set money to 10000

set y to abc

a.money -= 11000 # = a.money = a.money - 11000

out: get money

---------------------------------------------------------------------------

ValueError

---> 11 raise ValueError('money < 0')

12 print('set %s to %s' % (name, value))

13 object.__setattr__(self, name, value)

ValueError: money < 0

8.槽: __slots__

固定类所具有的属性

实例不会分配 __dict__

实例无法动态添加属性

优化内存分配, 大概能节约40%的内存.

class B:

__slots__ = ['x', 'y']

b = B()

b.x = 10

b.x

out: 10

b.z = 10

out: ---------------------------------------------------------------------------

AttributeError Traceback (most recent call last)

in ()

----> 1 b.z = 10

AttributeError: 'B' object has no attribute 'z'

b.__dict__ # 报错没有__dict__

out:---------------------------------------------------------------------------

AttributeError Traceback (most recent call last)

in ()

----> 1 b.__dict__

AttributeError: 'B' object has no attribute '__dict__'

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值