🧑 博主簡介:CSDN博客專家,歷代文學網(PC端可以訪問:https://literature.sinhy.com/#/literature?__c=1000,移動端可微信小程序搜索“歷代文學”)總架構師,
15年
工作經驗,精通Java編程
,高并發設計
,Springboot和微服務
,熟悉Linux
,ESXI虛擬化
以及云原生Docker和K8s
,熱衷于探索科技的邊界,并將理論知識轉化為實際應用。保持對新技術的好奇心,樂于分享所學,希望通過我的實踐經歷和見解,啟發他人的創新思維。在這里,我希望能與志同道合的朋友交流探討,共同進步,一起在技術的世界里不斷學習成長。
技術合作請加本人wx(注明來自csdn):foreast_sea
文章目錄
- Python進階編程總結
- 函數式編程
- 面向對象
- 變量
- 方法(存儲在內存中)
- 屬性(@property def func(self))
- 創建類的兩種方法
- 使用枚舉類(枚舉類不可比較大小,但是同一枚舉類的成員可以做等值is / not is判斷)
- 定義枚舉類
- 高級面向對象
- 元類types
- 元類type構造對象
- 使用Slot限制添加屬性
- 裝飾器
- python垃圾回收機制
- python 異常(Exception)、調試(Debug)、回溯(Traceback)
- 異常(Exception)
- 常見的異常:
- 調試(Debug)
- 單元測試
- 文檔測試(doctest)
- 回溯(Traceback)
- with 用法
- f_string 處理
- 數組復制的5種方法
Python進階編程總結
Python
作為一種功能強大且廣泛應用的編程語言,其進階編程領域蘊含著豐富的知識與技巧。在當今數字化快速發展的時代,深入掌握 Python
進階編程對于提升開發效率、優化代碼質量以及應對復雜項目需求有著至關重要的意義。
函數式編程提供了一種全新的編程范式,它強調將計算視為函數的求值過程,通過高階函數、匿名函數等特性,使代碼更加簡潔、靈活且易于維護。而面向對象編程則以類和對象為核心,通過合理定義變量、方法和屬性,構建出清晰的程序結構。無論是使用常規方式還是借助枚舉類來創建類,都為開發者提供了多樣化的選擇,以滿足不同場景的建模需求。
高級面向對象中的元類、Slot 機制
以及裝飾器等進一步拓展了 Python
的編程能力。元類能夠深入控制類的創建過程,Slot
可有效限制屬性添加從而優化內存使用,裝飾器則為代碼的動態增強提供了便捷手段。同時,理解 Python
的垃圾回收機制有助于更好地管理內存資源。
在程序運行過程中,異常處理、調試與回溯是保障程序穩定性和可維護性的關鍵環節。熟悉常見異常類型能讓我們快速定位和解決問題,單元測試和文檔測試為代碼質量保駕護航,回溯則清晰呈現錯誤發生的路徑。此外,with 用法簡化了資源管理,f_string 提供了高效的字符串格式化方式,數組復制的多種方法也為數據處理提供了更多靈活性。
本文將深入探討 Python
進階編程的這些核心要點,幫助讀者全面提升 Python
編程水平,更好地應對實際開發中的各種挑戰。
函數式編程
- 高階函數(參數里有函數類型)
map/reduce(functools.reduce())
filter
sorted
- 返回函數(返回函數類型)
- 匿名函數(
lambda
) - 裝飾器(
@:有參裝飾器、無參裝飾器,functools.wraps(function)
) - 偏函數(
functools.partor(function[,args,**kwords]
)
面向對象
變量
1.靜態字段
2.普通字段(self.value)
方法(存儲在內存中)
1.普通方法def func(self[,args])
2.類方法(@classmethod def func(cls[,args]))
3.靜態方法(@staticmethod def func())
屬性(@property def func(self))
1.靜態字段
2.裝飾類經典裝飾器
新裝飾器(使用方法模擬成員變量以及對成員變量的操作)方法一
繼承object@property object.funcName //user funcName to get the function return value like member value @funcName.setter object.func = value @funcName.deleter del object.funcName
方法二
創建property對象的靜態字段pro = property(get_value(),set_value(),del_value(),__doc__) obj = Object() ov = obj.pro obj.pro = value del obj.pro obj.pro.__doc__
類的特殊成員
__doc__
表示類的描述信息
__name__
類名
__bases__
類的所有父類構成的元組:tuple,不包含該類的type (類名即type類型使用(my_class,)
可獲得該類名的元組)
__mro__
類的繼承順序包含類本身<class ‘main.My_class’>,
__module__
表示當前操作的對象在那個模塊 packages.module
__class__
表示當前操作的對象的類 packages.module.class
__init__()
類的構造方法
__del__()
類的析構方法
__call__()
對象的方法 obj() self()
__getattr__()
當訪問obj不存在的屬性時會調用該方法getattr(obj, name, value) ==> obj.name 不存在該屬性返回value
name是函數name()需要添加@property 描述符
__dict__
類或對象中的所有成員
__str__
將類格式化成字符串 print(obj) 時調用,即toString()方法
__repr__
將類格式化成字符串 print(obj) 時調用,和__str__
的區別:更適合從編程語言上理解print(obj) [output:] class_name.method(self, arg1, arg2, ...)
__getitem__
用于索引操作[num],獲取數據
__setitem__
用于索引操作[num],設置數據
__delitem__
用于索引操作[num],刪除數據class mydict(object):def __getitem__(self, key):return self.keydef __setitem__(self, key, value):self.key = valuedef __delitem__(self, key):del self.keyobj = mydict()result = obj[key]obj['key'] = valuedel obj['key']
實現切片操作
__getitem__(self, n)
傳入的參數n 可能是int也可能是sliceclass Fib(object): def __getiter__(self, n):if isinstance(n, int):a, b = 1, 1for x in range(n):a, b = b, a + breturn aif isinstanece(n, slice):l = []slice.start = 0 if (slice.start is None)a, b = 1, 1for x in range(n.stop):if (x >= n.start and (x - n.start)%n.step == 0):l.append(a)a, b = b, a+breturn l
__getslice__
(self, i, j) obj[-1:1]
__setslice__
(self, i, j, sequence) obj[0:1] = [11,22,33,44]
__delslice__
(self, i, j) del obj[0:2]
__iter__
迭代器
__next__
配合__iter__
實現類的interable屬性
__new__
方法__new__(cls, name, bases, attrs)
類準備將自身實例化時調用,在__init__()
調用之前調用__new__()
,該方法是一個類方法@classmethodcls:當前準備創建的類的對象:type
name:類的名字:str
bases:類繼承的父類集合:class
attrs:類的方法集合:dict
__metaclass__
該屬性定義一個類的元類,即表示類該有哪個類(元類)來實例化
創建類的兩種方法
1.普通方法
class Object(object):def func(self):print('hello world!') object = Object()
2.特殊方法(元類type構造對象)
def func(self):print('Hello world!')object = type('Object', (object,), {'func':func}) #arg1:str 類名 ;arg2:tuple 基類; arg3:dict 成員;
類的創建過程
【CODE】class MyType(type):def __init__(self, what, bases=None, dict=None):super(MyType, self).__init__(what, bases, dict)def __call__(self, *args, **kwargs):obj = self.__new__(self, *args, **kwargs)self.__init__(obj) class Foo(object):__metaclass__ = MyTypedef __init__(self, name):self.name = namedef __new__(cls, *args, **kwargs):return object.__new__(cls, *args, **kwargs) # 第一階段:解釋器從上到下執行代碼創建Foo類 # 第二階段:通過Foo類創建obj對象 obj = Foo()
使用枚舉類(枚舉類不可比較大小,但是同一枚舉類的成員可以做等值is / not is判斷)
from enum import Enum month = Enum('Mouth',('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec')) for name ,member in month.__members__.items():print(f'{name}=>{member}=>{member.value}')
定義枚舉類
from enum import Enum, unique @unique#unique裝飾器幫助檢查Enum內部字段,保證字段不重復 class My_weekday(Enum):Sun = 0Mon = 1Tue = 2Wed = 3Thu = 4Fri = 5Sat = 6 my_weekday = My_weekday()#my_weekday.Sun print(my_weekday.Sun)#my_weekday.Sun print(my_weekday['Sun'])#my_weekday.Sun print(my_weekday(0))#my_weekday.Sun print(my_weekday.Sun.value)#0 for name, member in my_weekday.__members__.item():print(f'{name} {member} {member.value}') 【output】 """ Sun My_weekday.Sun 0 Mon My_weekday.Mon 1 Tue My_weekday.Tue 2 Wed My_weekday.Wed 3 Thu My_weekday.Thu 4 Fri My_weekday.Fri 5 Sat My_weekday.Sat 6 """
高級面向對象
元類types
動態地給對象添加方法(MethodType(func[, object/None], Object))
from types import MethodTypedef func(self, value):self.age = value class Student(object):def __init__(self,name):self.name = name student = Student('Bob') student.age_setter = MethodType(age_setter,func) student.age_setter(21) print(f'{student.name}is {student.age} years old.')
動態的給類添加方法
def func(self, value):self.age = value class Student(object):def __init__(self,name):self.name = name Student.age_setter = func Student.age_setter = MethodType(func, None, Student) student = Student('Bob') student.age_setter(21) print(f'{student.name}is {student.age} years old.')
元類type構造對象
def func(self):print('Hello world!') object = type('Object', (object,), {'func':func}) #arg1:str 類名 ;arg2:tuple 基類; arg3:dict('a' = a, 'b' = b...) 類變量/靜態字段;
使用Slot限制添加屬性
slot是一個特殊靜態字段,tuple類型.slot只對當前類起作用,對其子類并不起作用
class Student(object):__slot__ = ('name', 'age')def __init__(self, name, age):super(Student,self).__init__()self.name = nameself.age = age@propertydef name(self):return self.name@name.setterdef name(self,name):self.name = name@propertydef age(self):return self.age@age.setterdef age(self,name):self.age = age s1 = Student('Bill',21) s1.score = 89 [ERROR]:不能添加score字段
裝飾器
一般裝飾器(@decorate)
描述符裝飾器
實現了
__get__() __set__() __del__()@property @func.setter @func.deleter
數據描述符(實現了get set)
非數據描述符(只實現get 沒有實現set)
python垃圾回收機制
- 引用計數器(當一個對象被引用機會增加其引用計數,當不被引用時減少引用計數,減少至0時在合適的時機下內存被回收)
- 循環垃圾收集器(針對循環引用)
- 手動內存回收 del obj.obj (將引用計數置零,只有最后引用該內存的對象釋放后才執行析構函數__del__())
python 異常(Exception)、調試(Debug)、回溯(Traceback)
異常(Exception)
try:pass except Exception as e:raise else:pass finally:pass
常見的異常:
異常名稱 描述 BaseException 所有異常K的基類 SystemExit 解釋器請求退出 KeyboardInterrupt 用戶自行中斷執行^C Exception 常規錯誤的基類 StopIteration 迭代器溢出 GeneratorExit 生成器發生異常后通知退出 StandardError 所有標準異常類的基類 ArithmeticError 所有數值計算錯誤的基類 FloattingPointError 浮點計算錯誤 OverflowError 數值運算溢出 ZeroDivisionError 除[,取模]by0 AssertionError 斷言語句失敗 AttributeError 對象缺失該屬性 EOFError 沒有內建輸入,到達EOF標記 EnvironmentError 操作系統錯誤的基類 IOError 輸入/輸出操作失敗 OSError 操作系統錯誤 WindowsError 系統調用失敗 ImportError 導入模塊/對象失敗 LookupError 無效數據查詢的基類 IndexError 序列中沒有此索引 KeyError 映射中沒有此鍵 MemoryError 內存溢出(對于Python解釋起來說非致命) NameError 未聲明/初始化對象 UnboundLocalError 訪問未初始化的本地變量 ReferenceError 試圖訪問已被回收器回收的對象(弱引用) RuntimeError 一般運行時錯誤 NotImplementedError 尚未實現的方法 SyntaxError Python語法錯誤 IndentationError 縮進錯誤 TabError Tab和Space混用 SystemError 一般的解釋器系統錯誤 TypeError 對類型無效的操作 ValueError 傳入無效的參數 UnicodeError Unicode相關錯誤 UnicodeDecodeError Unicode解碼時的錯誤 UnicodeEncodeError Unicode編碼時的錯誤 UnicodeTranslateError Unicode轉碼時的錯誤 Warning 警告的基類 DeprecationWarning 關于被棄用的特性的警告 FutureWarning 關于構造將來語義會有改變的警告 OverflowWarning 舊的關于自動提升為長整型(long)的警告 pendingDeprecationWarning 關于特性將會被廢棄的警告 RuntimeWarning 可疑的運行時行為的警告 SysntaxWarning 可疑語法的警告 UserWarning 用戶代碼生成的警告
調試(Debug)
單元測試
單元測試的類在unittest包中使用時直接導入包
import unittest
.import unittest class TestClass(unitest.TestCase):def setUp(self):passdef tearDown(self):passdef test_init(self):self.assertEqual()self.assertTrue()self.assertRaises()def test_func1(self):passdef test_func2(self):pass
文檔測試(doctest)
Python的文檔測試模塊可以直接提取注釋中的代碼并執行
class Dict(dict):'''Simple dict but also support access as x.y style.>>> d1 = Dict()>>> d1['x'] = 100>>> d1.x100>>> d1.y = 200>>> d1['y']200>>> d2 = Dict(a=1, b=2, c='3')>>> d2.c'3'>>> d2['empty']Traceback (most recent call last):...KeyError: 'empty'>>> d2.emptyTraceback (most recent call last):...AttributeError: 'Dict' object has no attribute 'empty''''def __init__(self, **kw):super(Dict, self).__init__(**kw)def __getattr__(self, key):try:return self[key]except KeyError:raise AttributeError(r"'Dict' object has no attribute '%s'" % key)def __setattr__(self, key, value):self[key] = valueif __name__=='__main__':import doctestdoctest.testmod()
回溯(Traceback)
代碼
以下代碼功能相同import tracebacktraceback.print_exc() traceback.format_exc() traceback.print_exception(*ss.exc_info())
with 用法
事前事后用with(前后文管理器)
【version 1.0】 file = open("/src/tmp.txt") data = file.read() file.close() #可能會忘記關閉句柄 #可能會出現異常 【version 2.0】 file = open("/src/tmp.txt") try:data = file.read() finally:file.close() #總體結構安全性都有提升 【version 3.0 with】 with open("/src/tmp.txt") as file:data = file.read()
with 對處理對象需要自定義
__enter__() __exit__()
方法class Sample: def __enter__(self):print('function:enter')return "SAMPLE"def __exit__(self, type, value, trace):print('function:exit') def get_sample():return Sample()with get_sample() as sample:print(f'{sample}do somethings')[result:] function:enter SAMPLE do somethings function:exitclass Sample: def __init__(self, value):self.num = value def __enter__(self):print('function:enter')return selfdef __exit__(self, type, value, trace):print('function:exit')print('m_type:{type}\tm_value:{value}\ttrace:{trace})def func(self, value):return self.num/value def get_sample(num): return Sample(num)with get_sample() as sample:print(f'{sample}do somethings')num = input("input a number:")sample.func(num)#執行順序: #with 后面的函數/或type對象使用類的__init__()創建出一個對象,然后調用__enter__()方法將返回值賦給as 后的變量。在with執行完畢后調用類中的__exit__()方法,清理或關閉句柄。
open
(file, mode=‘r’, buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
f_string 處理
__str__,__repr__
__str __()
和__repr __()
方法處理對象如何呈現為字符串,因此您需要確保在類定義中包含至少一個這些方法。如果必須選擇一個,請使用__repr __()
,因為它可以代替__str __()
。__str __()
返回的字符串是對象的非正式字符串表示,應該可讀。__repr __()
返回的字符串是官方表示,應該是明確的。調用str()
和repr()
比直接使用__str __()
和__repr __()
更好。- 默認情況下,f字符串將使用
__str __()
,但如果包含轉換標志!r
,則可以確保它們使用__repr __()
。f"{new_comedian}" 'This __str__' f"{new_comedian!r}" 'This __repr__'
數組復制的5種方法
python中簡單將一個數組賦值給另一個數組,實際上是兩個引用指向同一塊內存,可能無法達到預期目的.因此這里整理了幾種數組拷貝復制的方法.
- 切片
newArr = oldArr[:]
- list()
newArr = list(oldArr)
- Arr*1
newArr = oldArr*1
- copy.copy()淺拷貝方法
newArr = copy.copy(oldArr) newArr = oldArr.copy()
- copy.deepcopy()深拷貝方法
newArr = copy.deepcopy(oldArr)