Python常见魔法方法详解

常用魔法方法

1. __str__()

当使用print输出对象的时候,只要自己定义了__str__(self)方法,那么就会打印从在这个方法中return的数据

	class Car:
	
	    def __init__(self, newWheelNum, newColor):
	        self.wheelNum = newWheelNum
	        self.color = newColor
	
	    def __str__(self):
	        msg = "嘿。。。我的颜色是" + self.color + "我有" + int(self.wheelNum) + "个轮胎..."
	        return msg
	
	    def move(self):
	        print('车在跑,目标:夏威夷')
	
	
	BMW = Car(4, "白色")
	print(BMW)

2. __del__()

创建对象后,python解释器默认调用__init__()方法;
当删除一个对象时,python解释器也会默认调用一个方法,这个方法为__del__()方法

import time
class Animal(object):

    # 初始化方法
    # 创建完对象后会自动被调用
    def __init__(self, name):
        print('__init__方法被调用')
        self.__name = name


    # 析构方法
    # 当对象被删除时,会自动被调用
    def __del__(self):
        print("__del__方法被调用")
        print("%s对象马上被干掉了..."%self.__name)

# 创建对象
dog = Animal("哈皮狗")

# 删除对象
del dog


cat = Animal("波斯猫")
cat2 = cat
cat3 = cat

print("---马上 删除cat对象")
del cat
print("---马上 删除cat2对象")
del cat2
print("---马上 删除cat3对象")
del cat3

print("程序2秒钟后结束")
time.sleep(2)

结果
在这里插入图片描述
总结

  • 当有1个变量保存了对象的引用时,此对象的引用计数就会加1
  • 当使用del删除变量指向的对象时,如果对象的引用计数不会1,比如3,那么此时只会让这个引用计数减1,即变为2,当再次调用del时,变为1,如果再调用1次del,此时会真的把对象进行删除

3. __call__()

__call__()的作用是使实例能够像函数一样被调用,对象后面加括号,触发执行。

  • __init__方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__方法的执行是由对象后加括号触发的,即:对象() 或者 类()
  • 当类的实例对象,实现该方法,就变成了可调用对象。
  • 被执行调用的时候,实际就是调用了call函数。

如下为应用在类装饰器上

class Test(object):
    def __init__(self, func):
        print("---初始化---")
        print("func name is %s"%func.__name__)
        self.__func = func
    def __call__(self):
        print("---装饰器中的功能---")
        self.__func()

4. __new__()

创建对象时,系统会自动调用__new__方法
开发者可以实现new方法来自定义对象的创建过程

class Cat:
	    def __new__(cls, name):
	        print("创建对象")
	        # return super().__new__(cls)
	        return object.__new__(cls)

	    def __init__(self, name):
	        print("对象初始化")
	        self.name = name

	    def __str__(self):
	        return "%s" % self.name


	lanmao = Cat("蓝猫")
	lanmao.age = 20
	print(lanmao)

总结:

  • __new__至少要有一个参数cls,代表要实例化的类,此参数在实例化时由Python解释器自动提供
  • __new__必须要有返回值,返回实例化出来的实例,这点在自己实现__new__时要特别注意,可以return父类__new__出来的实例,或者直接是object的__new__出来的实例
  • __init__有一个参数self,就是这个__new__返回的实例,__init__在__new__的基础上可以完成一些其它初始化的动作,__init__不需要返回值
  • 如果创建对象时传递了自定义参数,且重写了new方法,则new也必须 “预留” 该形参,否则init方法将无法获取到该参数

5. __del__()

  • 创建对象后,python解释器默认调用__init__()方法;
  • 当删除一个对象时,python解释器也会默认调用一个方法,这个方法为__del__()方法
  • 当有1个变量保存了某个对象的引用时,此对象的引用计数就会加1
  • 当使用del删除变量时,只有当变量指向的对象的所有引用都被删除后,也就是引用计数为0时,才会真删除该对象(释放内存空间),这时才会触发__del__()方法
  • 此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,__del__的调用是由解释器在进行垃圾回收时自动触发执行的。
import time

class Animal(object):

    # 初始化方法
    # 创建完对象后会自动被调用
    def __init__(self, name):
        print('__init__方法被调用')
        self.__name = name


    # 析构方法
    # 当对象被删除时,会自动被调用
    def __del__(self):
        print("__del__方法被调用")
        print("%s对象马上被干掉了..."%self.__name)

# 创建对象
dog = Animal("哈皮狗")

# 删除对象
del dog

cat = Animal("波斯猫")
cat2 = cat
cat3 = cat

print("---马上 删除cat的对象引用")
del cat
print("---马上 删除cat2的对象引用")
del cat2
print("---马上 删除cat3的对象引用")
del cat3

print("程序2秒钟后结束")
time.sleep(2)

执行结果

__init__方法被调用
__del__方法被调用
哈皮狗对象马上被干掉了...
__init__方法被调用
---马上 删除cat的对象引用
---马上 删除cat2的对象引用
---马上 删除cat3的对象引用
__del__方法被调用
波斯猫对象马上被干掉了...
程序2秒钟后结束

6. __init__()

如何让创建出来的对象包含一些默认属性,并且有初始值?
__init__()方法叫做 对象的初始化方法(也叫魔法方法),在 创建一个对象后默认会被调用,不需要手动调用
开发者可以 实现这个方法,并在该方法中定义属性并设置初始值

	class Cat:
	    # 初始化方法
	    def __init__(self):
	        # 设置对象的默认属性及初始值
	        self.type = "小型动物"

	# 创建了一个对象
	tom = Cat() 
	# 获取对象的属性
	print(tom.type)
6.1 __init__()自定义参数

如果对象默认属性的初始值不一样,怎么办?
__init__(self)除了默认参数self,还可以设置任意个数的自定义参数,例如__init__(self,x,y,z)
init方法 设置的自定义参数必须和创建对象时传递的参数保持一致,例如tom = Cat(x,y,z)
开发者可以 设置自定义参数,为对象的默认属性提供 不同的初始值
开发中,一般会在__init__()中定义对象的属性

class Cat:

    # 方法
    def __init__(self, new_name, new_age):
        """在创建完对象之后 会自动调用, 它完成对象的初始化的功能"""
        # self.name = "汤姆"  # 如果这里写"汤姆"的话,只要是用这个Cat创建的任何对象,都叫做“汤姆”,因此不能使用
        # self.age = 20
        self.name = new_name
        self.age = new_age

    def introduce(self):
        print("名字是:%s, 年龄是:%d" % (self.name, self.age))

# 创建了一个对象
tom = Cat("汤姆", 30)  

# 添加属性
# tom.name = "汤姆"
# tom.age = 30

# 获取属性
print(tom.name)
print(tom.age)
tom.introduce() # 相当于tom.introduce(tom)

print("="*30)

lan_mao = Cat("蓝猫", 20)
# lan_mao.name = "蓝猫"
# lan_mao.age = 20
lan_mao.introduce()

7. __getitem__()、__setitem__()、__delitem__()

用于索引操作,如字典。以上分别表示获取、设置、删除数据

class Foo(object):

    def __getitem__(self, key):
        print('__getitem__', key)

    def __setitem__(self, key, value):
        print('__setitem__', key, value)

    def __delitem__(self, key):
        print('__delitem__', key)


obj = Foo()

result = obj['k1']      # 自动触发执行 __getitem__
obj['k2'] = 'laowang'   # 自动触发执行 __setitem__
del obj['k1']           # 自动触发执行 __delitem__

结果

__getitem__ k1
__setitem__ k2 laowang
__delitem__ k1

8. __getslice__()、__setslice__()、__delslice__()

该三个方法用于分片操作,如:列表

class Foo(object):

    def __getslice__(self, i, j):
        print('__getslice__', i, j)

    def __setslice__(self, i, j, sequence):
        print('__setslice__', i, j)

    def __delslice__(self, i, j):
        print('__delslice__', i, j)

obj = Foo()

obj[-1:1]                   # 自动触发执行 __getslice__
obj[0:1] = [11,22,33,44]    # 自动触发执行 __setslice__
del obj[0:2]                # 自动触发执行 __delslice__
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值