python中的__init__、__new__、__call__

不知道大家在学习python的时候有没有遇到过这几个方法,我最近看了一下,下面这是我的理解
首先,先来说说__init__,这是一个初始化函数,是对你定义的类进行初始化的,对比我们的其他语言,是不是发现有什么区别,你不知道python的构造函数在哪。python类中的构造函数就是__new__了

	class Some(object):

    def __new__(cls, num):
        print('__new__')
        self = super().__new__(cls)
        print(self)
        return self

    def __init__(self, num):
        print('__init__')
        self.num = num
        print(self)


	some = Some(213)

我们执行以下这个代码来看一下结果

	__new__
	<__main__.Some object at 0x000001F11830CF98>
	__init__
	<__main__.Some object at 0x000001F11830CF98>

可以看到__new__函数是在__init__函数之前执行的,并且将实例化的对象传给__init__,当然,如果__new__没有返回实例对象的话,__init__将不会执行,这个很容易理解,连对象都没有实例化又怎么会执行初始化方法呢

重写__new__能干什么

我们可以重写__new__来实现单例模式和工厂模式
首先我们先来看一下单例模式
单例模式是指创建唯一对象,单例模式设计的类只能实例化1个对象,通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源

	class Some(object):
	    def __new__(cls, num):
	        if not hasattr(cls, '_instance'):
	            cls._instance = object.__new__(cls)
	        return cls._instance
	
	    def __init__(self, num):
	        self.num = num
	
	
	some_one = Some(213)
	some_two = Some(123)
	print('some_one: ', some_one)
	print('some_two: ', some_two)

运行一下看一下结果

	some_one:  <__main__.Some object at 0x0000017F3621CEB8>
	some_two:  <__main__.Some object at 0x0000017F3621CEB8>

两个指向了同一个地址,实现了单例模式,并且some_two实例里的num值会将some_one实例里的num值覆盖掉,这是因为又进行了一次初始化。
工厂模式
工厂模式包涵一个超类。这个超类提供一个抽象化的接口来创建一个特定类型的对象,而不是决定哪个对象可以被创建。

	class Animal(object):
	    def __init__(self, animal):
	        self.animal = animal
	
	    def output(self):
	        print(self.animal)
	
	
	class Car(object):
	    def __init__(self, car):
	        self.car = car
	
	    def output(self):
	        print(self.car)
	
	
	class People(object):
	    def __init__(self, people):
	        self.people = people
	
	    def output(self):
	        print(self.people)
	
	
	class Factory(object):
	    some = {"car": Car, "Animal": Animal}
	
	    def __new__(cls, name, other):
	        if name in cls.some.keys():
	            return cls.some[name](other)
	
	        else:
	            return People(other)
	
	    def __init__(self):
	        pass
	
	
	some_one = Factory("Car", "Car")
	some_one.output()
	some_two = Factory("Animal", "Animal")
	some_two.output()
	some_three = Factory("People", "People")
	some_three.output()

来看一下结果

	Car
	Animal
	People

__call__能干什么

再说之前我们先来看一下callable()是干什么用的。我们平时自定义的函数、内置函数和类都属于可调用对象,但凡是可以把一对括号()应用到某个对象身上都可称之为可调用对象,判断对象是否为可调用对象就需要用到callable(),直接上代码

	class Some(object):
	    def __init__(self, num):
	        self.num = num
	
	    def __call__(self, *args, **kwargs):
	        print("Yes, you do it!")
	        print(args)
	
	
	some = Some(123)
	print(callable(some))
	some(123234)

看一下结果

	True
	Yes, you do it!
	(123, 324)

很明显,实例化过后的对象some变成了一个可调用对象,并且我们还可以传入参数

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值