列表排序
list0 = [31, 24, 6, 3, 10, 19, 2]
list0.sort() # 升序排列
list0.sort(reverse=True) # 降序排列
print(list0)
反轉(zhuǎn)
如果是列表的話,可以直接用list.reverse()來(lái)實(shí)現(xiàn),其他可以考慮range(len(list), -1, -1)
Magic Method
多重繼承(菱形繼承)
理解兩個(gè)概念:
supper和mro(method resolution order)
super指的是 MRO 中的下一個(gè)類,而不是父類。 ## 這一點(diǎn)很重要
# -*- 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
最后,對(duì)于在子類中調(diào)用父類方法,要么直接使用父類名來(lái)調(diào)用方法,要么在子類中用super,保持一致,最好不要混用。
python單例模式的實(shí)現(xiàn)
單例模式(Singleton Pattern)是一種常用的軟件設(shè)計(jì)模式,該模式的主要目的是確保某一個(gè)類只有一個(gè)實(shí)例存在。當(dāng)你希望在整個(gè)系統(tǒng)中,某個(gè)類只能出現(xiàn)一個(gè)實(shí)例時(shí),單例對(duì)象就能派上用場(chǎng)。
比如,某個(gè)服務(wù)器程序的配置信息存放在一個(gè)文件中,客戶端通過(guò)一個(gè) AppConfig 的類來(lái)讀取配置文件的信息。如果在程序運(yùn)行期間,有很多地方都需要使用配置文件的內(nèi)容,也就是說(shuō),很多地方都需要?jiǎng)?chuàng)建 AppConfig 對(duì)象的實(shí)例,這就導(dǎo)致系統(tǒng)中存在多個(gè) AppConfig 的實(shí)例對(duì)象,而這樣會(huì)嚴(yán)重浪費(fèi)內(nèi)存資源,尤其是在配置文件內(nèi)容很多的情況下。事實(shí)上,類似 AppConfig 這樣的類,我們希望在程序運(yùn)行期間只存在一個(gè)實(shí)例對(duì)象。
在 Python 中,我們可以用多種方法來(lái)實(shí)現(xiàn)單例模式:
- 使用模塊
- 使用 new
- 使用裝飾器(decorator)
- 使用元類(metaclass)
模塊
我們只需把相關(guān)的函數(shù)和數(shù)據(jù)定義在一個(gè)模塊中,就可以獲得一個(gè)單例對(duì)象了。
# my_singleton.py
class Singleton(object):
def foo():
pass
my_singleton = Singleton()
# 然后在其他模塊中調(diào)用直接采用如下格式
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: 只拷貝父對(duì)象,不會(huì)拷貝對(duì)象的內(nèi)部的子對(duì)象
copy.deepcopy: 拷貝對(duì)象及其子對(duì)象
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']]
列表去重
# 方法一:轉(zhuǎn)集合再轉(zhuǎn)列表,會(huì)更改順序
org_list = [81, 24, 25, 8, 39, 24, 35, 35, 1, 8]
return list(set(org_list))
# 方法二:字典的fromkeys,會(huì)更改順序
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
# 方法四:函數(shù)和列表推導(dǎo),保持順序
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
# 有一種列表推導(dǎo)的方法跟這個(gè)類似
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的區(qū)別
append(object) —— object可以是str,list,dict等,把object作為一個(gè)整體追加在list的末尾
extend.(iterable) — 一個(gè)可迭代的對(duì)象,把這個(gè)對(duì)象的每個(gè)元素分別追加到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關(guān)鍵字用來(lái)在函數(shù)或其他局部作用域中使用全局變量。但是如果不修改全局變量也可以不使用global關(guān)鍵字
- 聲明全局變量,如果在局部要對(duì)全局變量修改,需要在局部也要先聲明該全局變量
# -*- coding: utf-8 -*-
gcount = 1
def global_test():
global gcount
gcount += 2
print(gcount)
global_test()
上面的例子如果在函數(shù)不聲明全局變量,則會(huì)報(bào)錯(cuò)。
- 在局部如果不聲明全局變量,并且不修改全局變量。則可以正常使用全局變量
gcount = 0
def global_test():
print(gcount)
global_test()
而nonlocal這個(gè)關(guān)鍵字是python3新引入的,之前如果要更改外部作用域里的變量,最簡(jiǎn)單的辦法就是將其放入全局作用域,用global關(guān)鍵字引入該變量。
現(xiàn)在只要在閉包內(nèi)用nonlocal聲明變量,就可以讓解釋器在外層函數(shù)中查找變量名了。
def a():
x = 1
def b():
nonlocal x
x += 1
print(x)
return b
a()()