python的魔法方法

本文详细介绍了Python中的魔法方法,包括__init__,__new__,__del__在对象创建和销毁时的角色,以及如何利用它们实现特定功能,如单例模式。同时,讨论了__str__和__repr__在对象转化为字符串时的作用。通过实例展示了这些方法如何影响对象的生命周期和行为。
摘要由CSDN通过智能技术生成

魔法方法总是杯双下划线包围,这是魔法方法的最大特点。

为什么称其为“魔法方法呢”?

他的魔力体现在他们总能够在适当的时候被自动调用。

魔法方法的第一个参数应为cls(类方法)或者self(实例方法)

  • cls:代表一个类的名称
  • self:代表一个实例对象的名称

基本的魔法方法

1、__init__(self[,...]):构造器,当一个实例被创建的时候调用的初始化方法

【例子】

class A():
    def __init__(self,x,y):
        self.x = x
        self.y = y
    def zhouchang(self):
        c = 2*(self.x+self.y)
        return c
    def area(self):
        s = self.x*self.y
        return s

a = A(2,5)              #该句创建对象时,会自动调用__init__方法来初始化对象
print(a.zhouchang())
print(a.area())

2、__new__(cls[,...]):在一个对象实例化的时候所调用的第一个方法,在调用__init__初始化前,先调用__new__

【注意点】__new__对当前类进行了实例化,并将实例返回,传给__init__self。但是,执行了__new__,并不一定会进入__init__,只有__new__返回了,当前类cls的实例,当前类的__init__才会进入。

【例子】

class A(object):
    def __init__(self):
        print('into A.init')

    def __new__(cls, *args, **kwargs):
        print('into A.new')
        print(cls)
        return object.__new__(cls)

class B(A):
    def __init__(self):
        print('into B.init')

    def __new__(cls, *args, **kwargs):
        print('into B.new')
        print(cls)
        return super().__new__(cls)

b = B()
#结果:
# into B.new
# <class '__main__.B'>
# into A.new
# <class '__main__.B'>
# into B.init
class C(object):
    def __init__(self):
        print('into C.init')

    def __new__(cls, *args, **kwargs):
        print('into C.new')
        print(cls)
        return object.__new__(cls)

class D(C):
    def __init__(self):
        print('into D.init')
    def __new__(cls, *args, **kwargs):
        print('into D.new')
        print(cls)
        return super().__new__(C)            #在这里做了改变,将原先的cls改成了C,这将导致无法给init方法传递正确的对象,因此不会执行D类中的init代码

d = D()

#结果
# into D.new
# <class '__main__.D'>
# into C.new
# <class '__main__.C'>

这两段代码说明的是:假如__new__没有正确返回当前类cls的实例,那__init__是不会被调用的,即使是父类的实例也不行,将没有__init__被调用。

【例子】利用__new__实现单例模式。

class A:
    __instance = None
    def __new__(cls, *args, **kwargs):
        if cls.__instance is None:
            cls.__instance = object.__new__(cls)
            return cls.__instance
        else:
            return cls.__instance
a = A()
b = A()
print(id(a))
print(id(b))

#结果
# 2898115563464
# 2898115563464
创建的两个对象是同一个

【例子】利用__new__继承一些不可变的 class 时(比如int, str, tuple), 提供给你一个自定义这些类的实例化过程的途径。

class CapStr(str):
    def __new__(cls, string,*args, **kwargs):
        string = string.upper()
        return str.__new__(cls,string)

s1 = CapStr('shi')            #SHI
print(s1)

3、del__(self) 析构器,当一个对象将要被系统回收之时调用的方法

Python 采用自动引用计数(ARC)方式来回收对象所占用的空间,当程序中有一个变量引用该 Python 对象时,Python 会自动保证该对象引用计数为 1;当程序中有两个变量引用该 Python 对象时,Python 会自动保证该对象引用计数为 2,依此类推,如果一个对象的引用计数变成了 0,则说明程序中不再有变量引用该对象,表明程序不再需要该对象,因此 Python 就会回收该对象。

大部分时候,Python 的 ARC 都能准确、高效地回收系统中的每个对象。但如果系统中出现循环引用的情况,比如对象 a 持有一个实例变量引用对象 b,而对象 b 又持有一个实例变量引用对象 a,此时两个对象的引用计数都是 1,而实际上程序已经不再有变量引用它们,系统应该回收它们,此时 Python 的垃圾回收器就可能没那么快,要等专门的循环垃圾回收器(Cyclic Garbage Collector)来检测并回收这种引用循环。

class A:
    def __init__(self):
        print('into A.init')
    def __del__(self):
        print('into A.del')

a = A()
a1 = a
a2 = a
del a1
del a2
del a

#结果
# into A.init
# into A.del

4、__str__(self):

  • 当你打印一个对象的时候,触发__str__
  • 当你使用%s格式化的时候,触发__str__
  • str强转数据类型的时候,触发__str__

5、_repr__(self):

  • reprstr的备胎
  • __str__的时候执行__str__,没有实现__str__的时候,执行__repr__
  • repr(obj)内置函数对应的结果是__repr__的返回值
  • 当你使用%r格式化的时候 触发__repr__

【例子】

import datetime

today = datetime.date.today()
print(str(today))  # 2019-10-11
print(repr(today))  # datetime.date(2019, 10, 11)
print('%s' %today)  # 2019-10-11
print('%r' %today)  # datetime.date(2019, 10, 11)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值