列表排序
list0 = [31, 24, 6, 3, 10, 19, 2]
list0.sort() # 升序排列
list0.sort(reverse=True) # 降序排列
print(list0)
反转
如果是列表的话,可以直接用list.reverse()来实现,其他可以考虑range(len(list), -1, -1)
Magic Method
多重继承(菱形继承)
理解两个概念:
supper和mro(method resolution order)
super指的是 MRO 中的下一个类,而不是父类。 ## 这一点很重要
# -*- coding: utf-8 -*-
class A(object):
def __init__(self):
print('welcome class A')
class B(A):
def __init__(self):
print('welcome class B')
super(B, self).__init__()
def extral(self):
print('welcome to extral B')
class C(A):
def __init__(self):
print('welcome class C')
super(C, self).__init__()
def extral(self):
print('welcome to extral C')
class D(C, B):
def __init__(self):
super(D, self).__init__()
if __name__ == '__main__':
# print(D.mro())
class_a = A()
class_b = B()
class_c = C()
class_D = D()
class_D.extral()
输出:
welcome class A
welcome class B
welcome class A
welcome class C
welcome class A
welcome class C
welcome class B
welcome class A
welcome to extral C
如果把C类中super那一行注释掉,则输出变成:
welcome class A
welcome class B
welcome class A
welcome class C
welcome class C
welcome to extral C
最后,对于在子类中调用父类方法,要么直接使用父类名来调用方法,要么在子类中用super,保持一致,最好不要混用。
python单例模式的实现
单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。
比如,某个服务器程序的配置信息存放在一个文件中,客户端通过一个 AppConfig 的类来读取配置文件的信息。如果在程序运行期间,有很多地方都需要使用配置文件的内容,也就是说,很多地方都需要创建 AppConfig 对象的实例,这就导致系统中存在多个 AppConfig 的实例对象,而这样会严重浪费内存资源,尤其是在配置文件内容很多的情况下。事实上,类似 AppConfig 这样的类,我们希望在程序运行期间只存在一个实例对象。
在 Python 中,我们可以用多种方法来实现单例模式:
- 使用模块
- 使用 new
- 使用装饰器(decorator)
- 使用元类(metaclass)
模块
我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了。
# my_singleton.py
class Singleton(object):
def foo():
pass
my_singleton = Singleton()
# 然后在其他模块中调用直接采用如下格式
from my_singleton import my_singleton
my_singleton.foo()
new
class Singleton(object):
_instance = None
def __new__(cls, *args, **kw):
if not cls._instance:
cls._instance = super(Singleton, cls).__new__(cls, *args, **kw)
return cls._instance
class MyClass(Singleton):
a = 1
装饰器
from functools import wraps
def singleton(cls):
instances = {}
@wraps(cls)
def getinstance(*args, **kw):
if cls not in instances:
instances[cls] = cls(*args, **kw)
return instances[cls]
return getinstance
@singleton
class MyClass(object):
a = 1
metaclass
class Singleton(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
return cls._instances[cls]
# Python2
class MyClass(object):
__metaclass__ = Singleton
# Python3
class MyClass(metaclass=Singleton):
pass
copy.copy和copy.deepcopy
copy.copy: 只拷贝父对象,不会拷贝对象的内部的子对象
copy.deepcopy: 拷贝对象及其子对象
a = [1,2,3,4,['a','b']]
b = copy.copy(a)
c = copy.deepcopy(a)
a.append(5)
a[4].append('c')
print(b)
print(c)
# 输出
[1,2,3,4,['a','b','c']]
[1,2,3,4,['a','b']]
列表去重
# 方法一:转集合再转列表,会更改顺序
org_list = [81, 24, 25, 8, 39, 24, 35, 35, 1, 8]
return list(set(org_list))
# 方法二:字典的fromkeys,会更改顺序
org_list = [81, 24, 25, 8, 39, 24, 35, 35, 1, 8]
return {}.fromkeys(org_list).keys() # python 2.x
# 如果是python 3.x版本,则换成return list({}.fromkeys(org_list).keys())
# 方法三:sort,保持顺序
org_list = [81, 24, 25, 8, 39, 24, 35, 35, 1, 8]
new_list = list(set(org_list))
new_list.sort(key=org_list.index)
return new_list
# 方法四:函数和列表推导,保持顺序
org_list = [81, 24, 25, 8, 39, 24, 35, 35, 1, 8]
new_list = []
for value in org_list:
if value not in new_list:
new_list.append(value)
return new_list
# 有一种列表推导的方法跟这个类似
org_list = [81, 24, 25, 8, 39, 24, 35, 35, 1, 8]
new_list = []
[new_list.append(i) for i in org_list if i not in new_list]
return new_list
# 方法五:reduce,保持顺序
org_list = [81, 24, 25, 8, 39, 24, 35, 35, 1, 8]
func = lambda x,y:x if y in x else x+[y]
return functools.reduce(func, [[]]+org_list)
append和extend的区别
append(object) —— object可以是str,list,dict等,把object作为一个整体追加在list的末尾
extend.(iterable) — 一个可迭代的对象,把这个对象的每个元素分别追加到list的末尾
org_list = ['welcome', 'to']
org_list.append(['my', 'home'])
print(org_list) # ['welcome', 'to', ['my', 'home']]
org_list = ['welcome', 'to']
org_list.extend(['my', 'home'])
print(org_list) # ['welcome', 'to', 'my', 'home']
global和nonlocal
global关键字用来在函数或其他局部作用域中使用全局变量。但是如果不修改全局变量也可以不使用global关键字
- 声明全局变量,如果在局部要对全局变量修改,需要在局部也要先声明该全局变量
# -*- coding: utf-8 -*-
gcount = 1
def global_test():
global gcount
gcount += 2
print(gcount)
global_test()
上面的例子如果在函数不声明全局变量,则会报错。
- 在局部如果不声明全局变量,并且不修改全局变量。则可以正常使用全局变量
gcount = 0
def global_test():
print(gcount)
global_test()
而nonlocal这个关键字是python3新引入的,之前如果要更改外部作用域里的变量,最简单的办法就是将其放入全局作用域,用global关键字引入该变量。
现在只要在闭包内用nonlocal声明变量,就可以让解释器在外层函数中查找变量名了。
def a():
x = 1
def b():
nonlocal x
x += 1
print(x)
return b
a()()