1、[ii for i in range(10)]和(ii for i in range(10))区别
一个是列表生成式,一个式迭代器
# 列表解析生成列表
>>> [i*i for i in range(10)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> a = [i*i for i in range(10)]
>>> type(a)
<class 'list'>
# 生成器表达式
>>> b = (i*i for i in range(10))
>>> b
<generator object <genexpr> at 0x102b11620>
>>> type(b)
<class 'generator'>
>>> # 两者之间转换
>>> list(b)
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
可参考:https://blog.csdn.net/qq_34358193/article/details/102911407,记录的式生成器和迭代器。
2、new()和__init__()区别,谁先执行
_new_() 是新式类中新出现的类方法,它在构造方法(_init_())之前调用。
__new__()的声明
def __new__(cls, *args, **kwargs):
pass
_new_()的参数和__init__()一样,但_init_()是在类实例创建之后调用,而_new_()方法正是创建类实例的方法。_init_()有一个参数self,self就是__new__()返回的实例,_init_()在__new__()的基础上完成一些其它初始化的动作,_init_()不需要返回值。
class Foo(object):
def __init__(self):
print '__init__'
def __new__(cls,*args,**kargs):
print '__new__'
return super(Foo,cls).__new__(cls,*args,**kargs)
f = Foo()
'''
__new__
__init__
'''
上述代码可证明__new__()方法的调用在__init__()之前。
执行过程如下
f = Foo()
执行Foo的__new__()方法,_new_()方法返回Foo的一个实例
执行__new__()方法返回实例的__init__()方法
由以上可知,_init_()和__new__()的区别主要有以下
_init_() 通常用于初始化一个新实例,控制实例的初始化过程,比如添加一些属性, 做一些额外的操作,发生在类实例被创建完以后,它是实例级别的方法
_new_() 通常用于控制生成一个新实例,它是类级别的方法
可利用__new__()实现单例模式
#!/usr/bin/python
# -*- coding: utf-8 -*-
class Singleton(object):
'''单例模式'''
def __init__(self):
print '__init__'
def __new__(cls,*args,**kargs):
if not cls.__dict__.get('_Singleton__instance'):
cls._Singleton__instance = super(Singleton,cls).__new__(cls,*args,**kargs)
return cls._Singleton__instance
m = Singleton()
n = Singleton()
print m is n
'''
__init__
__init__
True
'''
new() 的特性
new() 方法在类准备将自身实例化时调用;
new() 方法始终都是类的静态方法,即使没有被加上静态方法装饰器;
注意
如果在定义新式类时没有重定义__new__(),Python默认按照MRO顺序调用其父类的__new__()方法来构造该类的实例,因为object是所有新式类的基类,所以一定能找到__new__()方法;
如果新式类重写了__new__()方法,那么可以任意选择一个新式类的__new__()方法来制造实例;
(一定要是新式类,新式类必有__new__(),因为所有新式类都是object的后代,而经典类则没有__new__()方法)
如果__new__()没有返回当前类的实例,那么当前类的__init__()方法是不会被调用的;
如果__new__()返回其他类(新式类或经典类均可)的实例,那么会调用被返回的那个类的构造方法;
也就是说返回谁的实例,就调用谁的__init__()方法,不返回实例,不会调用__init__()方法
class Foo1(object):
def __init__(self, *args, **kwargs):
print "Foo1 __init__"
def __new__(cls, *args, **kwargs):
return super(Foo1,cls).__new__(cls, *args, **kwargs)
class Foo2(object):
def __init__(self):
print "Foo2 __init__"
def __new__(cls, *args, **kwargs):
'''返回Foo1的实例'''
return Foo1()
class Foo3(object):
def __init__(self):
print "Foo3 __init__"
def __new__(cls, *args, **kwargs):
pass
foo1 = Foo1() #Foo1 __init__
print type(foo1) #<class '__main__.Foo1'>
foo2 = Foo2() #Foo1 __init__,调用的是Foo1的__init__()方法
print type(foo2) #<class '__main__.Foo1'>
foo3 = Foo3()
print type(foo3) #<type 'NoneType'>
————————————————
版权声明:本文为CSDN博主「忧桑的小兔子」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lis_12/article/details/54631089
————————————————
参考链接:https://blog.csdn.net/lis_12/article/details/54631089
3、单例模式
单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。
1、基于 __new__方法实现(推荐使用,方便)
当我们实现单例时,为了保证线程安全需要在内部加入锁。
我们知道,当我们实例化一个对象时,是先执行了类的__new__方法(我们没写时,默认调用object._new_),实例化对象;然后再执行类的__init__方法,对这个对象进行初始化,所有我们可以基于这个,实现单例模式.
import threading
class Singleton(object):
_instance_lock = threading.Lock()
def __init__(self):
pass
def __new__(cls, *args, **kwargs):
if not hasattr(Singleton, "_instance"):
with Singleton._instance_lock:
if not hasattr(Singleton, "_instance"):
Singleton._instance = object.__new__(cls)
return Singleton._instance
obj1 = Singleton()
obj2 = Singleton()
print(obj1,obj2)
def task(arg):
obj = Singleton()
print(obj)
for i in range(10):
t = threading.Thread(target=task,args=[i,])
t.start()
#打印结果
<__main__.Singleton object at 0x038B33D0> <__main__.Singleton object at 0x038B33D0>
<__main__.Singleton object at 0x038B33D0>
<__main__.Singleton object at 0x038B33D0>
<__main__.Singleton object at 0x038B33D0>
<__main__.Singleton object at 0x038B33D0>
<__main__.Singleton object at 0x038B33D0>
<__main__.Singleton object at 0x038B33D0>
<__main__.Singleton object at 0x038B33D0>
<__main__.Singleton object at 0x038B33D0>
<__main__.Singleton object at 0x038B33D0>
<__main__.Singleton object at 0x038B33D0>
采用这种方式的单例模式,以后实例化对象时,和平时实例化对象的方法一样 obj = Singleton()
单例模式
实现单例模式的几种方式
1.使用模块
2.使用装饰器
3.使用类
4.基于__new__方法实现(推荐使用,方便)
5.基于metaclass方式实现
相关知识
实现单例模式
转载于:https://www.cnblogs.com/huchong/p/8244279.html
4、装饰器实现单例模式
def Singleton(cls):
_instance = {}
def _singleton(*args, **kargs):
if cls not in _instance:
_instance[cls] = cls(*args, **kargs)
return _instance[cls]
return _singleton
@Singleton
class A(object):
a = 1
def __init__(self, x=0):
self.x = x
#定制类
'''
__str__()返回用户看到的字符串,而__repr__()返回程序开发者看到的字符串,也就是说,__repr__()是为调试服务的。
解决办法是再定义一个__repr__()。但是通常__str__()和__repr__()代码都是一样的,所以,有个偷懒的写法
'''
def __str__(self):
return 'A object(x:%s)'%self.x
a1 = A(2)
a2 = A(3)
print(a1)
print(a2)
5、二叉树的序列化和反序列化
【题目】:
二叉树被记录成文件的过程叫作二叉树的序列化,通过文件内容重建原来二叉树的过程叫做二叉树的反序列化。给定一颗二叉树的头节点 head,并已知二叉树节点值的类型为32位整形。请设计一种二叉树序列化和反序列化的方案,并用代码实现。
【思路】:
解法为先序遍历和层遍历两种。
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution:
def __init__(self):
self.sIndex = 0
#序列化二叉树
#序遍历二叉树
def recursionSerialize(self, root):
series = ''
if root == None:
series += ',$'
else:
series += (',' + str(root.val))
series += self.recursionSerialize(root.left)
series += self.recursionSerialize(root.right)
return series
def Serialize(self, root):
return self.recursionSerialize(root)[1:]
'''
结果
root = TreeNode(11)
root.left = TreeNode(2)
root.right = TreeNode(3)
series = Solution().Serialize(root)
print(series)
>>>11,2,$,$,3,$,$
'''
'''
反序列化
先构建根节点,然后左节点,右节点,同样是递归
注意由于使用的是字符串的表示形式,可以先转化为list,
print(series.split(','))
>>>['11', '2', '$', '$', '3', '$', '$']
'''
def getValue(self, s, sIndex): #处理超过10的数字,将数字字符转变为数字
val = 0
while ord(s[sIndex]) <= ord('9') and ord(s[sIndex]) >= ord('0'):
val = val * 10 + int(s[sIndex])
sIndex += 1
return val, sIndex - 1
#下面是反序列化的递归函数:
def Deserialize(self, s):
if self.sIndex < len(s):
if s[self.sIndex] == ',':
self.sIndex += 1
if s[self.sIndex] == '$':
return None
val, self.sIndex = self.getValue(s, self.sIndex)
treeNode = TreeNode(val)
self.sIndex += 1
treeNode.left = self.Deserialize(s)
self.sIndex += 1
treeNode.right = self.Deserialize(s)
return treeNode
转载:https://www.jb51.net/article/157217.htm