pythonmainoffset_python之(22)基础总结(5)
1、Python3 面向對象
1.面向對象技術簡介
類(Class):用來描述具有相同的屬性和方法的對象的集合。它定義了該集合中每個對象所共有的屬性和方法。對象是類的實例。
方法:類中定義的函數。
類變量:類變量在整個實例化的對象中是公用的。類變量定義在類中且在函數體之外。類變量通常不作為實例變量使用。
數據成員:類變量或者實例變量用于處理類及其實例對象的相關的數據。
方法重寫:如果從父類繼承的方法不能滿足子類的需求,可以對其進行改寫,這個過程叫方法的覆蓋(override),也稱為方法的重寫。
局部變量:定義在方法中的變量,只作用于當前實例的類。
實例變量:在類的聲明中,屬性是用變量來表示的,這種變量就稱為實例變量,實例變量就是一個用 self 修飾的變量。
繼承:即一個派生類(derived class)繼承基類(base class)的字段和方法。繼承也允許把一個派生類的對象作為一個基類對象對待。例如,有這樣一個設計:一個Dog類型的對象派生自Animal類,這是模擬"是一個(is-a)"關系(例圖,Dog是一個Animal)。
實例化:創建一個類的實例,類的具體對象。
對象:通過類定義的數據結構實例。對象包括兩個數據成員(類變量和實例變量)和方法。
和其它編程語言相比,Python 在盡可能不增加新的語法和語義的情況下加入了類機制。
Python中的類提供了面向對象編程的所有基本功能:類的繼承機制允許多個基類,派生類可以覆蓋基類中的任何方法,方法中可以調用基類中的同名方法。
對象可以包含任意數量和類型的數據。
2.類定義
類實例化后,可以使用其屬性,實際上,創建一個類之后,可以通過類名訪問其屬性。
3、類對象
類對象支持兩種操作:屬性引用和實例化。
屬性引用使用和 Python 中所有的屬性引用一樣的標準語法:obj.name。
4、類的方法
在類的內部,使用 def 關鍵字來定義一個方法,與一般函數定義不同,類方法必須包含參數 self, 且為第一個參數,self 代表的是類的實例。
注意:def__init__(self,...........):是構造方法
#類定義
classpeople:#定義基本屬性
name = ''age=0#定義私有屬性,私有屬性在類外部無法直接進行訪問
__weight =0#定義構造方法
def __init__(self, n, a, w):
self.name=n
self.age=a
self.__weight =wdefspeak(self):print("%s說:我已經%d歲了,體重%d斤" % (self.name, self.age, self.__weight))#實例化類
p = people('rancor', 10, 30)
p.speak()
結果:
C:\Anaconda3\envs\FlinkUdf\python.exe C:/app/FlinkUdf/src/main/Python/Practice/Test.py
rancor說:我已經10歲了,體重30斤
Process finished with exit code 0
5、繼承
①單繼承
class DerivedClassName(modname.BaseClassName):
測試:
#!/usr/bin/python3
#類定義
classpeople:#定義基本屬性
name = ''age=0#定義私有屬性,私有屬性在類外部無法直接進行訪問
__weight =0#定義構造方法
def __init__(self, n, a, w):
self.name=n
self.age=a
self.__weight =wdefspeak(self):print("%s 說: 我 %d 歲。" %(self.name, self.age))#單繼承示例
classstudent(people):
grade= ''
def __init__(self, n, a, w, g):#調用父類的構函
people.__init__(self, n, a, w)
self.grade=g#覆寫父類的方法
defspeak(self):print("%s 說: 我 %d 歲了,體重%d斤,我在讀 %d 年級" %(self.name, self.age, self.grade))
s= student('ken', 10, 60, 3)
s.speak()
結果:
C:\Anaconda3\envs\FlinkUdf\python.exe C:/app/FlinkUdf/src/main/Python/Practice/Test.py
ken 說: 我10 歲了,我在讀 3年級
Process finished with exit code 0
注意:私有屬性的定義是:_+屬性名(_weight),其中私有屬性不能被子類所訪問
②多繼承
class sample(speaker, student):
需要注意圓括號中父類的順序,若是父類中有相同的方法名,而在子類使用時未指定,python從左至右搜索 即方法在子類中未找到時,從左到右查找父類中是否包含方法。即
方法名同,默認調用的是在括號中排前面的父類的方法
①父類中有相同的方法名時:
#!/usr/bin/python3
#類定義
classpeople:#定義基本屬性
name = ''age=0#定義私有屬性,私有屬性在類外部無法直接進行訪問
__weight =0#定義構造方法
def __init__(self, n, a, w):
self.name=n
self.age=a
self.__weight =wdefspeak(self):print("%s 說: 我 %d 歲。" %(self.name, self.age))#單繼承示例
classstudent(people):
grade= ''
def __init__(self, n, a, w, g):#調用父類的構函
people.__init__(self, n, a, w)
self.grade=g#覆寫父類的方法
defspeak(self):print("%s 說: 我 %d 歲了,我在讀 %d 年級" %(self.name, self.age, self.grade))#另一個類,多重繼承之前的準備
classspeaker():
topic= ''name= ''
def __init__(self, n, t):
self.name=n
self.topic=tdefspeak(self):print("我叫 %s,我是一個演說家,我演講的主題是 %s" %(self.name, self.topic))#多重繼承
classsample(speaker, student):
a= ''
def __init__(self, n, a, w, g, t):
student.__init__(self, n, a, w, g)
speaker.__init__(self, n, t)
test= sample("Tim", 25, 80, 4, "Python")
test.speak()#方法名同,默認調用的是在括號中排前地父類的方法
②父類中不存在相同的方法名
#!/usr/bin/python3
#類定義
classpeople:#定義基本屬性
name = ''age=0#定義私有屬性,私有屬性在類外部無法直接進行訪問
__weight =0#定義構造方法
def __init__(self, n, a, w):
self.name=n
self.age=a
self.__weight =wdefspeak(self):print("%s 說: 我 %d 歲。" %(self.name, self.age))#單繼承示例
classstudent(people):
grade= ''
def __init__(self, n, a, w, g):#調用父類的構函
people.__init__(self, n, a, w)
self.grade=g#覆寫父類的方法
defspeak(self):print("%s 說: 我 %d 歲了,我在讀 %d 年級" %(self.name, self.age, self.grade))#另一個類,多重繼承之前的準備
classspeaker:
topic= ''name= ''
def __init__(self, n, t):
self.name=n
self.topic=tdefspeak1(self):print("我叫 %s,我是一個演說家,我演講的主題是 %s" %(self.name, self.topic))#多重繼承
classsample(speaker, student):
a= ''
def __init__(self, n, a, w, g, t):
student.__init__(self, n, a, w, g)
speaker.__init__(self, n, t)
test= sample("Tim", 25, 80, 4, "Python")
test.speak()#方法名同,默認調用的是在括號中排前面的父類的方法
test.speak1()
結果:
C:\Anaconda3\envs\FlinkUdf\python.exe C:/app/FlinkUdf/src/main/Python/Practice/Test.py
Tim 說: 我25 歲了,我在讀 4年級
我叫 Tim,我是一個演說家,我演講的主題是 Python
Process finished with exit code 0
6、方法重寫
如果你的父類方法的功能不能滿足你的需求,你可以在子類重寫你父類的方法,其中super() 函數是用于調用父類(超類)的一個方法
classpeople:
name= ''sex= ''age=0#私有化ID卡
_telPhone = ''
#定義構造方法
def __init__(self, n, s, a, telPhone):
self.name=n;
self.sex=s;
self.age=a;
self._telPhone=telPhonedefshow(self):print("我是%s,性別%s,年齡%d歲,手機號是%s" %(self.name, self.sex, self.age, self._telPhone))#單繼承
classstudent(people):
grade= ''
def __init__(self, n, s, a, telPhone, g):
people.__init__(self, n, s, a, telPhone)
self.grade=gdefshow(self):print("我是%s,性別%s,年齡%d歲,在讀%s年級" %(self.name, self.sex, self.age, self.grade))#注意實例化類一定得有()
s = student('ruboo', '男', 12, '12345678910', '三')
s.show()
super(student, s).show()
結果:
C:\Anaconda3\envs\FlinkUdf\python.exe C:/app/FlinkUdf/src/main/Python/Practice/Test.py
我是ruboo,性別男,年齡12歲,在讀三年級
我是ruboo,性別男,年齡12歲,手機號是12345678910
Process finished with exit code 0
注意:實例化類一定得加()。調用方法時方法也得加()
7、類的屬性和方法
類的私有屬性
__private_attrs:兩個下劃線開頭,聲明該屬性為私有,不能在類的外部被使用或直接訪問。在類內部的方法中使用時 self.__private_attrs。
類的方法
在類的內部,使用 def 關鍵字來定義一個方法,與一般函數定義不同,類方法必須包含參數 self,且為第一個參數,self 代表的是類的實例。
self 的名字并不是規定死的,也可以使用 this,但是最好還是按照約定是用 self。
類的私有方法
__private_method:兩個下劃線開頭,聲明該方法為私有方法,只能在類的內部調用 ,不能在類的外部調用。self.__private_methods。
注意實例化不能訪問私有屬性和私有方法,不過可以通過在本類中非私有化的方法是調用類的私有屬性或者私有方法再進行實例化訪問
8、類的專有方法
__init__ : 構造函數,在生成對象時調用
__del__ : 析構函數,釋放對象時使用
__repr__ : 打印,轉換
__setitem__ : 按照索引賦值
__getitem__: 按照索引獲取值
__len__: 獲得長度
__cmp__: 比較運算
__call__: 函數調用
__add__: 加運算
__sub__: 減運算
__mul__: 乘運算
__truediv__: 除運算
__mod__: 求余運算
__pow__: 乘方
9、運算符重載
實現兩兩數求加減乘除
classVector:def __init__(self, a, b):
self.a=a
self.b=b#重載字符串函數
def __str__(self):return 'Vector (%d, %d)' %(self.a, self.b)#重載加法運算符
def __add__(self, other):return Vector(self.a + other.a, self.b +other.b)#重載減法運算符
def __sub__(self, other):return Vector(self.a - other.a, self.b -self.b)#重載乘法運算符
def __mul__(self, other):return Vector(self.a * other.a, self.a *self.b)#重載除法運算符
def __truediv__(self, other):return Vector(self.a / other.a, self.b /other.b)
v1= Vector(20, 10)
v2= Vector(5, 2)print(v1 +v2)print(v1 -v2)print(v1 *v2)print(v1 / v2)
結果:
C:\Anaconda3\envs\FlinkUdf\python.exe C:/app/FlinkUdf/src/main/Python/Practice/Test.py
Vector (25, 12)
Vector (15, 0)
Vector (100, 200)
Vector (4, 5)
Process finished with exit code 0
2、Python3 命名空間和作用域
1、命名空間
命名空間(Namespace)是從名稱到對象的映射,大部分的命名空間都是通過 Python 字典來實現的。
命名空間提供了在項目中避免名字沖突的一種方法。各個命名空間是獨立的,沒有任何關系的,所以一個命名空間中不能有重名,但不同的命名空間是可以重名而沒有任何影響。
我們舉一個計算機系統中的例子,一個文件夾(目錄)中可以包含多個文件夾,每個文件夾中不能有相同的文件名,但不同文件夾中的文件可以重名。
一般有三種命名空間:
內置名稱(built-in names), Python 語言內置的名稱,比如函數名 abs、char 和異常名稱 BaseException、Exception 等等。
全局名稱(global names),模塊中定義的名稱,記錄了模塊的變量,包括函數、類、其它導入的模塊、模塊級的變量和常量。
局部名稱(local names),函數中定義的名稱,記錄了函數的變量,包括函數的參數和局部定義的變量。(類中定義的也是)
命名空間查找順序:
假設我們要使用變量 runoob,則 Python 的查找順序為:局部的命名空間去 -> 全局命名空間 -> 內置命名空間。
如果找不到變量 runoob,它將放棄查找并引發一個 NameError 異常:
命名空間的生命周期:
命名空間的生命周期取決于對象的作用域,如果對象執行完成,則該命名空間的生命周期就結束。
因此,我們無法從外部命名空間訪問內部命名空間的對象。
相同的對象名稱可以存在于多個命名空間中。
#var1 是全局名稱
var1 = 5
defsome_func():#var2 是局部名稱
var2 = 6
defsome_inner_func():#var3 是內嵌的局部名稱
var3 = 7
2、作用域
作用域就是一個 Python 程序可以直接訪問命名空間的正文區域。
在一個 python 程序中,直接訪問一個變量,會從內到外依次訪問所有的作用域直到找到,否則會報未定義的錯誤。
Python 中,程序的變量并不是在哪個位置都可以訪問的,訪問權限決定于這個變量是在哪里賦值的。
變量的作用域決定了在哪一部分程序可以訪問哪個特定的變量名稱。Python的作用域一共有4種,分別是:
有四種作用域:
L(Local):最內層,包含局部變量,比如一個函數/方法內部。
E(Enclosing):包含了非局部(non-local)也非全局(non-global)的變量。比如兩個嵌套函數,一個函數(或類) A 里面又包含了一個函數 B ,那么對于 B 中的名稱來說 A 中的作用域就為 nonlocal。
G(Global):當前腳本的最外層,比如當前模塊的全局變量。
B(Built-in): 包含了內建的變量/關鍵字等。,最后被搜索
規則順序: L –> E –> G –>gt; B。
在局部找不到,便會去局部外的局部找(例如閉包),再找不到就會去全局找,再者去內置中找。
1、內置作用域是通過一個名為 builtin 的標準模塊來實現的,但是這個變量名自身并沒有放入內置作用域內,所以必須導入這個文件才能夠使用它
2、Python 中只有模塊(module),類(class)以及函數(def、lambda)才會引入新的作用域,其它的代碼塊(如 if/elif/else/、try/except、for/while等)是不會引入新的作用域的,也就是說這些語句內定義的變量,外部也可以訪問
#只有模塊(module),類(class)以及函數(def、lambda)才會引入新的作用域,其它的代碼塊(如 if/elif/else/、try/except、for/while等)是不會引入新的作用域的
ifTrue:#這里定義一個局部作用域
msg = 'I am from Runoob'
#局部作用域調用這個局部命名空間
print(msg)#全局作用域去調用局部命名空間,但是模塊,類和函數是不能在外部去調用局部命名空間的,注意這里的模塊相當于包的概念
print(msg)
C:\Anaconda3\envs\FlinkUdf\python.exe C:/app/FlinkUdf/src/main/Python/Practice/Test.py
I amfromRunoob
I amfromRunoob
Process finished with exit code 0
3、全局變量和局部變量
定義在函數內部的變量擁有一個局部作用域,定義在函數外的擁有全局作用域。
局部變量只能在其被聲明的函數內部訪問,而全局變量可以在整個程序范圍內訪問。調用函數時,所有在函數內聲明的變量名稱都將被加入到作用域中。
4、局部變量如何改為全局變量
1、非嵌套的情況下:
使用global進行修改
num = 1
deffun1():#全局變量變為局部變量
globalnum#輸出全局變量
print(num)#重新賦值變量
num = 123
print(num)
fun1()print(num)
結果:
C:\Anaconda3\envs\FlinkUdf\python.exe C:/app/FlinkUdf/src/main/Python/Practice/Test.py1
123
123Process finished with exit code 0
2、嵌套情況下使用nonlocal
defouter():
num= 10
definner():#全局變量修改為局部變量
nonlocal num #nonlocal關鍵字聲明
num = 100
print(num)
inner()print(num)
outer()
結果:
C:\Anaconda3\envs\FlinkUdf\python.exe C:/app/FlinkUdf/src/main/Python/Practice/Test.py100
100Process finished with exit code 0
注意:nonlocal和global不能一起使用
3、Python3 標準庫概覽
1、操作系統接口
os模塊提供了不少與操作系統相關聯的函數。
import os
2、日常的文件和目錄管理任務
importshutil
shutil.copyfile('data.db', 'archive.db')
shutil.move('/build/executables', 'installdir')
3、文件通配符
glob模塊提供了一個函數用于從目錄通配符搜索中生成文件列表:
importglobprint(glob.glob('*.py'))
C:\Anaconda3\envs\FlinkUdf\python.exe C:/app/FlinkUdf/src/main/Python/Practice/Test.py
['Test.py']
Process finished with exit code 0
4、命令行參數
通用工具腳本經常調用命令行參數
importsysprint(sys.argv)print(sys.api_version)print(sys.float_info)print(sys.maxsize)
結果:
C:\Anaconda3\envs\FlinkUdf\python.exe C:/app/FlinkUdf/src/main/Python/Practice/Test.py
['C:/app/FlinkUdf/src/main/Python/Practice/Test.py']1013sys.float_info(max=1.7976931348623157e+308, max_exp=1024, max_10_exp=308, min=2.2250738585072014e-308, min_exp=-1021, min_10_exp=-307, dig=15, mant_dig=53, epsilon=2.220446049250313e-16, radix=2, rounds=1)9223372036854775807Process finished with exit code 0
5、錯誤輸出重定向和程序終止
sys 還有 stdin,stdout 和 stderr 屬性,即使在 stdout 被重定向時,后者也可以用于顯示警告和錯誤信息。
importsysprint(sys.argv)print(sys.api_version)print(sys.float_info)print(sys.maxsize)print(sys.modules)print(sys.stderr.write('Warning, log file not found starting a new one\n'))
結果:
C:\Anaconda3\envs\FlinkUdf\python.exe C:/app/FlinkUdf/src/main/Python/Practice/Test.py
['C:/app/FlinkUdf/src/main/Python/Practice/Test.py']1013sys.float_info(max=1.7976931348623157e+308, max_exp=1024, max_10_exp=308, min=2.2250738585072014e-308, min_exp=-1021, min_10_exp=-307, dig=15, mant_dig=53, epsilon=2.220446049250313e-16, radix=2, rounds=1)9223372036854775807{'sys': , 'builtins': , '_frozen_importlib': , '_imp': , '_thread': , '_warnings': , '_weakref': , 'zipimport': , '_frozen_importlib_external': , '_io': , 'marshal': , 'nt': , 'winreg': , 'encodings': , 'codecs': , '_codecs': , 'encodings.aliases': , 'encodings.utf_8': , '_signal': , '__main__': , 'encodings.latin_1': , 'io': , 'abc': , '_abc': , 'site': , 'os': , 'stat': , '_stat': , '_collections_abc': , 'ntpath': , 'genericpath': , 'os.path': , '_sitebuiltins': , '_bootlocale': , '_locale': , 'encodings.gbk': , '_codecs_cn': , '_multibytecodec': , 'sitecustomize': }47Warning, log filenotfound starting a new one
Process finished with exit code 0
大多腳本的定向終止都使用 "sys.exit()"。
6、字符串正則匹配
re模塊為高級字符串處理提供了正則表達式工具。對于復雜的匹配和處理,正則表達式提供了簡潔、優化的解決方案:
importreprint(re.findall(r'\bf[a-z]*', 'which foot or hand fell fastest'))print(re.sub(r'(\b[a-z]+) \1', r'\1', 'cat in the the hat'))print('tea for too'.replace('too', 'two'))
結果:
C:\Anaconda3\envs\FlinkUdf\python.exe C:/app/FlinkUdf/src/main/Python/Practice/Test.py
['foot', 'fell', 'fastest']
catinthe hat
teafortwo
Process finished with exit code 0
7、數學
math模塊為浮點運算提供了對底層C函數庫的訪問:
random提供了生成隨機數的工具。
importmathimportrandomprint(math.acosh(10))print(math.e)print(random.choice(['apple', 'pear', 'banana']))print(random.sample(range(100), 10))print(random.random())print(random.randrange(6))
結果:
C:\Anaconda3\envs\FlinkUdf\python.exe C:/app/FlinkUdf/src/main/Python/Practice/Test.py2.993222846126381
2.718281828459045pear
[37, 66, 81, 75, 95, 24, 13, 16, 25, 9]0.3879468875255455
4Process finished with exit code 0
注意:隨機生成一個浮點數random.random(),隨機生成一個整數random.randrange(6)
8、日期和時間
datetime模塊為日期和時間處理同時提供了簡單和復雜的方法。
支持日期和時間算法的同時,實現的重點放在更有效的處理和格式化輸出。
該模塊還支持時區處理:
importdatetimefrom datetime importdateprint(date.today())print(datetime.date(2003, 12, 2))print((date.today()-datetime.date(2003, 12, 2)).days)
結果:
C:\Anaconda3\envs\FlinkUdf\python.exe C:/app/FlinkUdf/src/main/Python/Practice/Test.py2020-11-26
2003-12-02
6204Process finished with exit code 0
9、數據壓縮
以下模塊直接支持通用的數據打包和壓縮格式:zlib,gzip,bz2,zipfile,以及 tarfile。
importzlib
s= b'witch which has which witches wrist watch'
print('壓縮前大小:', len(s))print('壓縮后大小:', len(zlib.compress(s)))print('解壓后內容是:', zlib.decompress(zlib.compress(s)))print('解壓后大小:', len(zlib.decompress(zlib.compress(s))))print(zlib.crc32(s))
結果:
C:\Anaconda3\envs\FlinkUdf\python.exe C:/app/FlinkUdf/src/main/Python/Practice/Test.py
壓縮前大小:41壓縮后大小:37解壓后內容是: b'witch which has which witches wrist watch'解壓后大小:41
226805979Process finished with exit code 0
10、性能度量
有些用戶對了解解決同一問題的不同方法之間的性能差異很感興趣。Python 提供了一個度量工具,為這些問題提供了直接答案。
例如,使用元組封裝和拆封來交換元素看起來要比使用傳統的方法要誘人的多,timeit 證明了現代的方法更快一些。
from timeit importTimerprint(Timer('t=a; a=b; b=t', 'a=1; b=2').timeit())print(Timer('a,b = b,a', 'a=1; b=2').timeit())
結果:
C:\Anaconda3\envs\FlinkUdf\python.exe C:/app/FlinkUdf/src/main/Python/Practice/Test.py0.0666407790000001
0.06026570400000009Process finished with exit code 0
相對于 timeit 的細粒度,:mod:profile 和 pstats 模塊提供了針對更大代碼塊的時間度量工具。
11、測試模塊
開發高質量軟件的方法之一是為每一個函數開發測試代碼,并且在開發過程中經常進行測試
doctest模塊提供了一個工具,掃描模塊并根據程序中內嵌的文檔字符串執行測試。
測試構造如同簡單的將它的輸出結果剪切并粘貼到文檔字符串中。
通過用戶提供的例子,它強化了文檔,允許 doctest 模塊確認代碼的結果是否與文檔一致:
importdoctestdefaverage(values):"""Computes the arithmetic mean of a list of numbers.
>>> print(average([20, 30, 70]))
40.0"""
return sum(values) /len(values)
doctest.testmod()#自動驗證嵌入測試
結果:
C:\Anaconda3\envs\FlinkUdf\python.exe C:/app/FlinkUdf/src/main/Python/Practice/Test.py
Process finished with exit code 0
unittest模塊不像 doctest模塊那么容易使用,不過它可以在一個獨立的文件里提供一個更全面的測試集:
importdoctestdefaverage(values):"""Computes the arithmetic mean of a list of numbers.
>>> print(average([20, 30, 70]))
40.0"""
return sum(values) /len(values)
doctest.testmod()#自動驗證嵌入測試
importunittestclassTestStatisticalFunctions(unittest.TestCase):deftest_average(self):
self.assertEqual(average([20, 30, 70]), 40.0)
self.assertEqual(round(average([1, 5, 7]), 1), 4.3)
self.assertRaises(ZeroDivisionError, average, [])
self.assertRaises(TypeError, average,20, 30, 70)
unittest.main()#Calling from the command line invokes all tests
結果:
C:\Anaconda3\envs\FlinkUdf\python.exe C:/app/FlinkUdf/src/main/Python/Practice/Test.py
.----------------------------------------------------------------------Ran1 test in0.001s
OK
Process finished with exit code 0
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的pythonmainoffset_python之(22)基础总结(5)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python简单体育竞技模拟_Pytho
- 下一篇: python免费入门_python入门