python中的构造方法和 __new__, __init__

构造方法是什么?

没有特别的规定, 一般认为是在类中用来创建对象的方法, 例如在 java 中, 每个类中有一个与类同名的方法, 人们把它称为构造方法 如下. 它的作用是构造并实例化对象. 在python中, 这个功能通过两个函数来实现. 我认为 __new__方法和 __init__方法共同实现了类似于java中构造方法的作用.

public class People {
	People(Integer age, String name) {
		this.name = name;
		this.age = age
	}
}

People p = new People(18, "ttt")  // p 是一个对象, People() 是构造方法

__init__ 和 __new__

class Student(Object):
	def __init__(self, name):
		self.name = name
	
	def __new__(cls, name):
		return super(Student, self).__new__(name)

s = Student('ttt')
""" s 是一个对象, 但这个过程是通过 __new__ 和 __init__ 共同实现的"""

python中实现单例的方式

参考知乎单例实现方式
线程安全的单例模式的实现

import threading


def synchronized(func):
    func.__lock__ = threading.Lock()
    def lock_func(*args, **kwargs):
        with func.__lock__:
            return func(*args, **kwargs)
    return lock_func
    
class Student(object):
	_instance = None
	def __init__(self, *args):
		self.args = args
	
    @synchronized
	def __new__(cls, *args, **kwargs):
		print('before', *args, "  ", cls._instance)
		if cls._instance is None:
			cls._instance = super(Student, cls).__new__(cls)
		print('after', *args, " ", cls._instance)			
		return cls._instance


s1 = Student('aaa')
s2 = Student('bbb')
s3 = Student('ccc')
print(s1.args, s2.args, s3.args)
"""
我期望是 一下输出:
aaa, bbb, ccc

实际输出是:
before aaa    None
after aaa   <__main__.Student object at 0x000002B5FCCCF8D0>
before bbb    <__main__.Student object at 0x000002B5FCCCF8D0>
after bbb   <__main__.Student object at 0x000002B5FCCCF8D0>
before ccc    <__main__.Student object at 0x000002B5FCCCF8D0>
after ccc   <__main__.Student object at 0x000002B5FCCCF8D0>
('ccc',) ('ccc',) ('ccc',)
"""		

本文想要说明的是 __new__
__init__共同实现了构造方法的功能, 可以看到, 对象被创建了.<__main__.Student object at 0x000002B5FCCCF8D0>, 但是在被多次创建时没有多次创建对象, 而只创建一个对象内存空间, 但这个内存空间被多次实例化, 这不是我想要的单例模式的功能. 但在这里我只想要说的就是 __new__ 和__intit__ 共同实现了 类似于 Java 的构造方法的功能.

附录

python 中单例模式的实现

  1. 使用元类
class SingletonType(type):
    def __init__(self, *args, **kwargs):
        super(SingletonType,self).__init__(*args,**kwargs)

    def __call__(cls, *args, **kwargs): # 这里的cls,即Foo类
        print('cls',cls)
        obj = cls.__new__(cls,*args, **kwargs)
        cls.__init__(obj,*args, **kwargs) # Foo.__init__(obj)
        return obj

class Foo(metaclass=SingletonType): # 指定创建Foo的type为SingletonType
    def __init__(self, name):
        self.name = name
    def __new__(cls, *args, **kwargs):
        return object.__new__(cls)

obj = Foo('xx')
obj2 = Foo('yy')
print(obj.name, obj2.name)
"""
result: 

cls <class '__main__.Foo'>
cls <class '__main__.Foo'>
xx yy	
"""
  1. 使用模块当单例使用, 用时导入
  2. 使用类装饰器
def sigleton(cls):
	_instance = dict()
	def func(*args, **kwargs):
		if cls not in _instance:
			print(_instance)
			_instance[cls] = cls(*args, **kwargs)
		return _instance[cls]
	return func

@sigleton
class A(object):
	def __init__(self, name):
		self.name = name
		
a = A('ttt')
b = A('ggg')
print(a.name, b.name)		
"""
results:
	ttt, ttt
"""

综上所述, 目前网上常用的实现单例模式的方法除了 装饰器方法 外, 都是实现了只创建一个对象, 但没有实现只初始化一次的功能, 要想实现只创建一个对象, 且只初始化一次, 可以考虑使用装饰器的方法
单例模式: 百度百科

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值