-
在進(jìn)行文件操作的時候,正確關(guān)閉一個文件非常重要,如果在文件讀寫后,沒有正確關(guān)閉一個文件的話,則有可能導(dǎo)致文件損壞,文件內(nèi)容丟失等問題。
我們使用文件對象的close()方法,來關(guān)閉一個文件。但是,使用close()方法,也不是100%安全的,如果在close()文件之前,程序異常退出了,那么文件也得不到正確的關(guān)閉。
在實(shí)際工程中,close()文件之前,為了正確關(guān)閉文件,需要考慮各種異常情況,這是非常麻煩的一件事,Python提供with關(guān)鍵字,可以免除這類后顧之憂。
with關(guān)鍵字對資源進(jìn)行訪問的場合,會確保不管在使用過程中是否發(fā)生異常,都會執(zhí)行必要的“清理”的操作,釋放資源,比如文件使用后自動關(guān)閉等等。with的使用方法如下:
with?open('test.txt',?'r')?as?f: ????content?=?f.readlines() ????for?line?in?content: ????????print(line)
當(dāng)文件使用結(jié)束后,不需要顯式的調(diào)用f.close()關(guān)閉文件。
任務(wù)
假設(shè)test.txt文件有以下內(nèi)容:
Hello?World Hello?Python Hello?Imooc
請使用with語法,將文件的內(nèi)容重復(fù)寫一份追加到文件的尾部。
#?coding=utf-8 with?open('C:\\Users\\呂成鑫\\Desktop\\test.txt',?'a+')?as?f: ????f.seek(0)??#?文件游標(biāo)置首位 ????content?=?f.readlines()?????#?讀取文件所有內(nèi)容 ????f.seek(2)??#?文件游標(biāo)置尾部 ????f.writelines(content)???#?追加寫入文件尾部 ????#?for?line?in?content: ???????#?f.write(line)
查看全部 -
通過w的打開方式打開文件,會清空文件的內(nèi)容,這在很多場景下是不合適的,比如寫系統(tǒng)日志的時候,需要累積隨時間推移的所有數(shù)據(jù)。
Python提供文件追加內(nèi)容的打開模式,可以往文件尾部添加內(nèi)容,又不清空文件原有的內(nèi)容。
模式:
a????打開一個文件并追加內(nèi)容,會往文件尾部添加內(nèi)容
? ?
ab????以二進(jìn)制格式打開一個文件并追加內(nèi)容,會往文件尾部添加內(nèi)容
? ?
a+????打開一個文件并使用追加進(jìn)行讀寫
使用a的打開方式打開文件,文件游標(biāo)默認(rèn)是在文件的尾部,因此,可以便捷的往文件尾部添加內(nèi)容,除此以外,文件對象還提供seek()方法,可以移動文件的游標(biāo)位置,它接受一個參數(shù),表示文件的位置:
????????0:文件首部,
????????1:當(dāng)前位置,
????????2:文件尾部
通過seek()可以把文件游標(biāo)移動到文件首部但不刪除文件的內(nèi)容。
任務(wù):
# 假設(shè)test.txt文件有以下內(nèi)容:
Hello?World Hello?Python Hello?Imooc
請將文件的內(nèi)容重復(fù)寫一份追加到文件的尾部。
#?coding=utf-8 f1?=?open('C:\\Users\\呂成鑫\\Desktop\\test.txt',?'a+') f1.seek(0) content?=?f1.readlines() f1.seek(2) f1.writelines(content) f1.close()
查看全部 -
要把字符串內(nèi)容寫入文件,需要使用w的模式打開文件。
模式:? ?
w????打開一個文件進(jìn)行寫入,如果文件內(nèi)容已存在,會清除原有的內(nèi)容
wb????以二進(jìn)制格式只寫模式打開一個文件,會清除原有的內(nèi)容
? ?
w+????打開一個文件進(jìn)行讀寫,如果文件內(nèi)容已存在,會清除原有的內(nèi)容
1. 寫入若干字符
文件對象提供write(string)方法向文件內(nèi)寫入若干字符,它接受一個字符串參數(shù),表示需要寫入的字符串。
2. 寫入若干行
文件對象提供writelines()方法向文件內(nèi)容寫入多行數(shù)據(jù),它接受一個列表,表示需要寫入的字符串列表。
任務(wù):
# 有test.txt文件,包含以下內(nèi)容:
Hello?World Hello?Python Hello?Imooc
請從test.txt文件讀取以上內(nèi)容,并將每一行字符串反轉(zhuǎn),寫入test1.txt文件。
dlroW?olleH nohtyP?olleH coomI?olleH
f1?=?open('C:\\Users\\呂成鑫\\Desktop\\test.txt',?'r') lines?=?f1.readlines() lines2?=?[] f2?=?open('C:\\Users\\呂成鑫\\Desktop\\test1.txt',?'w') for?line?in?lines: line?=?''.join(reversed(line[:-1])) line?+=?'\n' lines2.append(line) f2.writelines(lines2) f1.close() f2.close()
注意:
1. 字符串反轉(zhuǎn)可以使用切片實(shí)現(xiàn): reverse = str_[::-1]
2. 換行符是'\n',字符串反轉(zhuǎn)的時候,換行符也會翻轉(zhuǎn)
查看全部 -
打開文件之后,就可以讀取文件的內(nèi)容,文件對象提供多種讀取文件內(nèi)容的方法。
1. 讀取若干字符:
文件對象提供read()方法,可以讀取文件中的若干個字符,它提供一個參數(shù)size,可以指定讀取字符的數(shù)量。
test.txt內(nèi)容:
Hello?World. Hello?Python. Hello?Imooc.
s?=?f.read(5) print(s)?#?==>?Hello s?=?f.read(6) print(s)?#?==>?'?World'
當(dāng)read()之后,訪問文件的游標(biāo)就會移動到第六個字符前面,此時,繼續(xù)read,將得到Hello后面的結(jié)果。
2. 讀取一行:
文件對象提供readline()方法,和read()方法類似,可以讀取文件中的若干個字符,它也提供一個參數(shù)size,可以指定讀取字符的數(shù)量,不過和read()方法不同的是,readline()方法遇到一行結(jié)束時就返回。
readline最多返回一行的所有字符。
3. 讀取多行:
文件對象提供readlines()方法,可以讀取多行字符,返回一個列表。它提供一個hint參數(shù),表示指定讀取的行數(shù),沒有指定則默認(rèn)以列表的形式返回文件所有的字符串。
任務(wù):
# 實(shí)現(xiàn)一個read.py文件,把read.py文件的內(nèi)容打印出來。
#?coding=utf-8 f?=?open('C:\\Users\\呂成鑫\\Desktop\\test2.py',?'r') content?=?f.readlines() print(content) f.close()
查看全部 -
除了文本以外,還有大量的非文本文件,比如圖片、壓縮文件、視頻文件、音樂文件等等,這種文件統(tǒng)稱為二進(jìn)制文件,在Python中打開二進(jìn)制文件,需要不同的打開模式。
模式:
b????二進(jìn)制模式,打開二進(jìn)制文件
? ?
wb????以二進(jìn)制格式只寫模式打開一個文件,會清除原有的內(nèi)容
? ?
ab????以二進(jìn)制格式打開一個文件并追加內(nèi)容,會往文件尾部添加內(nèi)容
? ?
rb????以二進(jìn)制格式只讀模式打開一個文件
? ?
任務(wù):
# 請嘗試用只讀模式打開一個指定絕對路徑的二進(jìn)制文件,并正確關(guān)閉。
#?coding=utf-8 f?=?open('C:\\Users\\呂成鑫\\Desktop\\1.png',?'rb') print(f.type()) f.close()
查看全部 -
通過print()可以從數(shù)據(jù)輸出數(shù)據(jù),通過input()可以向程序輸入數(shù)據(jù),但這些都是標(biāo)準(zhǔn)屏幕上的操作,本節(jié)課學(xué)習(xí)文件的讀寫操作。
open()函數(shù)可以打開一個文件,得到一個文件file對象,而file對象提供相關(guān)的方法對文件內(nèi)容進(jìn)行讀寫等操作。
open()函數(shù)有若干個參數(shù),比較重要的是以下三個參數(shù):
????1. 文件路徑:指定需要打開的文件的文件路徑。
????2. 打開模式:針對不同文件(二進(jìn)制文件、文本文件)以及不同操作(讀操作、寫操作),會有不同的打開模式。
????3. 編碼:設(shè)定打開文件的默認(rèn)編碼。
常見模式:
t????文本模式(默認(rèn))。
? ?
x????寫模式,新建一個文件。
? ?
b????二進(jìn)制模式,打開二進(jìn)制文件。
? ?
+????更新一個文件(可讀可寫)。
r????以只讀模式打開一個文件。
rb????以二進(jìn)制格式只讀模式打開一個文件。
? ?
w????打開一個文件進(jìn)行寫入,如果文件內(nèi)容已存在,會清除原有的內(nèi)容。
wb????以二進(jìn)制格式只寫模式打開一個文件,會清除原有的內(nèi)容。
a????打開一個文件并追加內(nèi)容,會往文件尾部添加內(nèi)容。
ab????以二進(jìn)制格式打開一個文件并追加內(nèi)容,會往文件尾部添加內(nèi)容。
w+????打開一個文件進(jìn)行讀寫,如果文件內(nèi)容已存在,會清除原有的內(nèi)容。
a+????打開一個文件并使用追加進(jìn)行讀寫。
注意:為了安全操作文件,文件使用完畢后,需要使用close()函數(shù)正確關(guān)閉。
注意:在打開文本文件是并不需要特別指定模式t,因?yàn)槟J(rèn)就是以文本方式打開文件的。
任務(wù):
# 請嘗試以只讀模式打開一個指定絕對路徑的文本文件,并正確關(guān)閉。
#?coding=utf-8 f?=?open('C:\\Users\\呂成鑫\\Desktop\\L1.txt',?'r') print(type(f)) f.close()
當(dāng)執(zhí)行f.close()后,繼續(xù)執(zhí)行type(f)不報錯,而繼續(xù)執(zhí)行print(f.read())就會報錯:
查看全部 -
input()函數(shù)可以接收外部的輸入。
注意:輸入的是字符串,需要轉(zhuǎn)型為數(shù)字類型。
num?=?input('please?input?number:?') num?=?int(num)
任務(wù):
# eval()函數(shù)可以把字符串轉(zhuǎn)換為等值的結(jié)果,比如eval('1+1'),得到結(jié)果為2。請使用eval實(shí)現(xiàn)一個簡單的計算器,可以輸入表達(dá)式并打印計算結(jié)果。
#?coding=utf-8 while?True: s?=?input('請輸入表達(dá)式獲取結(jié)果,輸入break結(jié)束:') if?s?==?'break': break; res?=?eval(s) print(res)
查看全部 -
Python的官方模塊已經(jīng)提供了非常強(qiáng)大的能力。
大量熱心開發(fā)者提供了非常好用的第三方庫,在實(shí)際開發(fā)中,也會經(jīng)常使用,比如Web開發(fā)框架:Django、Flask,異步任務(wù)框架:Celery等。
Python環(huán)境提供了安裝第三方模塊的工具:pip,通過這個工具,可以非??旖莸陌惭b第三方模塊。
安裝Django模塊:pip install django
卸載Django模塊:pip uninstall django
任務(wù):
# requests是一個好用的HTTP模塊,請通過pip安裝該模塊
pip?install?requests
查看全部 -
導(dǎo)入官方模塊的時候,不需要考慮路徑問題,這是因?yàn)樵谒阉髂K的時候,會默認(rèn)包含官方模塊的路徑,所以導(dǎo)入官方模塊不需要考慮路徑的問題。
如果需要導(dǎo)入自定義模塊,則需要了解Python導(dǎo)入模塊搜索的路徑。通過sys模塊,可以知道導(dǎo)入模塊的路徑。
>>>?import?sys >>>?sys.path ['',?'/data/miniconda3/lib/python3.8',?'/data/miniconda3/lib/python3.8/site-packages']
返回的是一個列表,表示的是在搜索Python模塊時,會搜索的路徑。
第一個路徑是'',它是一個空字符串,表達(dá)的是當(dāng)前路徑的意思。
第二個路徑是/data/miniconda3/lib/python3.8,它是Python默認(rèn)模塊的存放的路徑,在這個路徑下,可以發(fā)現(xiàn)有os、sys等模塊的代碼。
第三個路徑是/data/miniconda3/lib/python3.8/site-packages,它是第三方模塊代碼的存放路徑,在這個路徑下,存放的是需要安裝的第三方模塊。
因?yàn)樵谒阉靼穆窂綍r,會搜索當(dāng)前路徑(上述:sys.path結(jié)果的第一項(xiàng)),因此在同一個目錄內(nèi)的tools.py模塊,可以被搜索到,所以能夠import進(jìn)來。
任務(wù):
# Python的sys.path返回的是一個路徑列表,因此可以操作列表里面的元素,請通過sys.path增加路徑'../',使得在運(yùn)行時,可以導(dǎo)入當(dāng)前目錄上級目錄的包。
#?coding=utf-8 import?sys lists?=?sys.path??#?列表的引用 p?=?'../'???????#?需要追加進(jìn)列表的路徑 lists.append(p)?????#?追加操作 print(sys.path)???#?打印列表結(jié)果
查看全部 -
要使用一個模塊,我們必須首先導(dǎo)入該模塊。Python使用import語句導(dǎo)入一個模塊,Python官方提供很多有用的模塊,比如:os模塊、sys模塊、time模塊、math模塊等等。
導(dǎo)入官方模塊,不需要考慮路徑的問題,直接導(dǎo)入即可。如果是導(dǎo)入自定義模塊,則需要考慮路徑問題。
導(dǎo)入官方模塊math:import math
導(dǎo)入以后,你就可以認(rèn)為math是一個指向已導(dǎo)入模塊的變量,通過該變量,我們可以訪問math模塊中所定義的所有公開的函數(shù)、變量和類。
如果希望導(dǎo)入模塊的指定部分屬性或函數(shù),那么使用from...import...語句。
如果希望導(dǎo)入模塊里面的所有內(nèi)容,那么使用from ...import *語句。
如果從一個模塊導(dǎo)入函數(shù),有可能會遇到導(dǎo)入的函數(shù)與本文件的函數(shù)沖突的情況。有兩種方法可以解決這個問題,第一種是直接導(dǎo)入模塊,不指定導(dǎo)入模塊里面的具體內(nèi)容;第二種方法就是使用from ... import as ...語句,as類似重命名,可以把導(dǎo)入的函數(shù)或?qū)傩灾孛麨閯e的名字。
任務(wù):
# math模塊還提供了非常多的數(shù)學(xué)計算函數(shù),比如:正弦sin()函數(shù),余弦cos()函數(shù),請使用兩種導(dǎo)入的方式,使用這兩個函數(shù)。
#?coding=utf-8 import?math??? x?=?math.sin(60)??#?(不加math會報錯) y?=?math.cos(60) print(x) print(y) #?from?math?import?sin,cos #?x?=?sin(45)???#?(加了math會報錯) #?y?=?cos(60) #?print(x) #?print(y)
查看全部 -
要使用一個模塊,我們必須首先導(dǎo)入該模塊。Python使用import語句導(dǎo)入一個模塊,Python官方提供很多有用的模塊,比如:os模塊、sys模塊、time模塊、math模塊等等。
導(dǎo)入官方模塊,不需要考慮路徑的問題,直接導(dǎo)入即可。如果是導(dǎo)入自定義模塊,則需要考慮路徑問題。
導(dǎo)入官方模塊math:import math
導(dǎo)入以后,你就可以認(rèn)為math是一個指向已導(dǎo)入模塊的變量,通過該變量,我們可以訪問math模塊中所定義的所有公開的函數(shù)、變量和類。
如果希望導(dǎo)入模塊的指定部分屬性或函數(shù),那么使用from...import...語句。
如果希望導(dǎo)入模塊里面的所有內(nèi)容,那么使用from ...import *語句。
如果從一個模塊導(dǎo)入函數(shù),有可能會遇到導(dǎo)入的函數(shù)與本文件的函數(shù)沖突的情況。有兩種方法可以解決這個問題,第一種是直接導(dǎo)入模塊,不指定導(dǎo)入模塊里面的具體內(nèi)容;第二種方法就是使用from ... import as ...語句,as類似重命名,可以把導(dǎo)入的函數(shù)或?qū)傩灾孛麨閯e的名字。
任務(wù):
# math模塊還提供了非常多的數(shù)學(xué)計算函數(shù),比如:正弦sin()函數(shù),余弦cos()函數(shù),請使用兩種導(dǎo)入的方式,使用這兩個函數(shù)。
# coding=utf-8
import math? ?
x = math.sin(60)? # (不加math會報錯)
y = math.cos(60)
print(x)
print(y)
# from math import sin,cos
# x = sin(45)? ?# (加了math會報錯)
# y = cos(60)
# print(x)
# print(y)
查看全部 -
要使用一個模塊,我們必須首先導(dǎo)入該模塊。Python使用import語句導(dǎo)入一個模塊,Python官方提供很多有用的模塊,比如:os模塊、sys模塊、time模塊、math模塊等等。
導(dǎo)入官方模塊,不需要考慮路徑的問題,直接導(dǎo)入即可。如果是導(dǎo)入自定義模塊,則需要考慮路徑問題。
導(dǎo)入官方模塊math:import math
導(dǎo)入以后,你就可以認(rèn)為math是一個指向已導(dǎo)入模塊的變量,通過該變量,我們可以訪問math模塊中所定義的所有公開的函數(shù)、變量和類。
如果希望導(dǎo)入模塊的指定部分屬性或函數(shù),那么使用from...import...語句。
如果希望導(dǎo)入模塊里面的所有內(nèi)容,那么使用from ...import *語句。
如果從一個模塊導(dǎo)入函數(shù),有可能會遇到導(dǎo)入的函數(shù)與本文件的函數(shù)沖突的情況。有兩種方法可以解決這個問題,第一種是直接導(dǎo)入模塊,不指定導(dǎo)入模塊里面的具體內(nèi)容;第二種方法就是使用from ... import as ...語句,as類似重命名,可以把導(dǎo)入的函數(shù)或?qū)傩灾孛麨閯e的名字。
任務(wù):
# math模塊還提供了非常多的數(shù)學(xué)計算函數(shù),比如:正弦sin()函數(shù),余弦cos()函數(shù),請使用兩種導(dǎo)入的方式,使用這兩個函數(shù)。
# coding=utf-8
import math? ?
x = math.sin(60)? # (不加math會報錯)
y = math.cos(60)
print(x)
print(y)
# from math import sin,cos
# x = sin(45)? ?# (加了math會報錯)
# y = cos(60)
# print(x)
# print(y)
查看全部 -
Python語言本身提供了非常多的模塊,比如數(shù)學(xué)模塊math、cmath、decimal、statistics;文件模塊pathlib、stat、shutil等;除了使用官方模塊,有時候也需要自定義模塊。
任務(wù):
# 定義一個公共模塊common.py,在common.py中,包含公共函數(shù)say_hello(name),它接受一個參數(shù),輸出:Hello 的結(jié)果。
#?coding=utf-8 #?common.py def?say_hello(name): ????tamplate?=?'Hello,?{n}' ????res?=?tamplate.format(n?=?name) ????print(res) ???? say_hello('綠花')
查看全部 -
Python模塊和包:
????模塊的出現(xiàn):
所有代碼都寫在一個py文件中,難以維護(hù)
把代碼按功能劃分到不同的文件
????常見代碼分類:
工具功能的代碼:tools.py
公共函數(shù)的代碼:common.py
第三方相關(guān)引入的代碼:thirdparty.py
????模塊分類:
官方模塊
自定義模塊
第三方模塊
????包的出現(xiàn):
模塊多了,難以維護(hù)
把模塊劃分到不同的包
查看全部 -
Python中,函數(shù)其實(shí)是一個對象,我們可以將一個函數(shù)賦值給一個變量,而不改變函數(shù)的功能。
把內(nèi)建函數(shù)abs()賦值給變量f之后,可以看到f就和abs一樣,都是函數(shù)。
由于 f 可以被調(diào)用,所以,f 被稱為可調(diào)用對象,而事實(shí)上,所有的函數(shù)都是可調(diào)用對象。
如果把一個類實(shí)例也變成一個可調(diào)用對象,可以用一個特殊的方法__call__()實(shí)現(xiàn)。
class?Person(object): ????def?__init__(self,?name,?gender): ????????self.name?=?name ????????self.gender?=?gender ????def?__call__(self,?friend): ????????print('My?name?is?{}...'.format(self.name)) ????????print('My?friend?is?{}...'.format(friend))
接著我們初始化一個Person對象,并對這個對象通過函數(shù)的方式調(diào)用:
>>>?p?=?Person('Bob',?'Male') >>>?p('Alice')?#?==>?用函數(shù)的方式調(diào)用Person類的實(shí)例p My?name?is?Bob... My?friend?is?Alice...
任務(wù):
# 請實(shí)現(xiàn)前面介紹過的斐波那契數(shù)列類Fib,加入__call__方法,使得調(diào)用的方式如下。
#?coding=utf-8 class?Fib(object): ????def?__init__(self): ????????self.fibs?=?[] ???? ????def?__call__(self,?num): ????????a?=?0 ????????b?=?1? ????????for?i?in?range(num): ????????????self.fibs.append(a) ????????????a?=?b ????????????b?=?a?+?b ????????return?self.fibs f?=?Fib() print(f(10))
查看全部 -
由于Python是動態(tài)語言,任何實(shí)例在運(yùn)行期都可以動態(tài)地添加屬性。
如果要限制添加的屬性,例如,Student類只允許添加 name、gender和score 這3個屬性,就可以利用Python的一個特殊的__slots__來實(shí)現(xiàn)。
使用__slots__ = ('name', 'gender', 'score') 限定Student類的屬性,這個時候在外部再次添加動態(tài)屬性age,將會報錯。
__slots__的目的是限制當(dāng)前類所能擁有的屬性,避免因?yàn)橥獠繉傩缘牟僮鲗?dǎo)致類屬性越來越難以管理。
任務(wù):
#?假設(shè)Person類通過__slots__定義了name和gender,請在派生類Student中通過__slots__繼續(xù)添加score的定義,使Student類可以實(shí)現(xiàn)name、gender和score 3個屬性。
#?coding=utf-8 #?人類: class?Person(object): ????__slots__?=?('name',?'gender') ????def?__init__(self,?name,?gender): ????????self.name?=?name ????????self.gender?=?gender ????def?__str__(self): ????????return?'Person(name:{},?gender:{})'.format(self.name,?self.gender) #?學(xué)生類: class?Student(Person): ????#?__slots__?=?('name',?'gender',?'score') ????__slots__?=?('score',)? ????def?__init__(self,?name,?gender,?score): ????????super(Student,?self).__init__(name,?gender) ????????self.score?=?score ????def?__str__(self): ????????return?'Student(name:{},?gender:{},?score:{})'.format(self.name,?self.gender,?self.score) #?實(shí)例化: p1?=?Person('蓮華',?'女') #?p1.age?=?22???#?報錯:AttributeError:?'Person'?object?has?no?attribute?'age' #?print(p1.age)? print(p1) s1?=?Student('萬里',?'男',?100) print(s1)
查看全部 -
Python很多的操作都是通過內(nèi)建函數(shù)來實(shí)現(xiàn)的,比如最熟悉的加、減、乘、除,都是通過內(nèi)建函數(shù)來實(shí)現(xiàn)的,分別是__add__、__sub__、__mul__、__truediv__。因此,只要我們的自定義類實(shí)現(xiàn)了相關(guān)的內(nèi)建函數(shù),我們的類對象,也可以做到加減乘除。
p、q 都是整數(shù),表示有理數(shù) p/q。
注意__add__()函數(shù),它有一個參數(shù),表示的是運(yùn)算的第二個操作數(shù),比如:r1 + r2,那么在__add__()方法中的參數(shù),r指的就是r2,這個參數(shù)是運(yùn)算符重載的時候傳遞的。
除法的特殊方法名字較長__truediv__,并且含有true這樣的描述,這其實(shí)和Python除法是有關(guān)系的。
Python的除法可以分為地板除和普通除法,地板除的特殊方法是__floordiv__,普通除法是__truediv__。地板除法的結(jié)果只會向下取整數(shù)。普通除法使用/表示,而地板除使用//表示。任務(wù):
# Rational類雖然可以做加法,但無法做減法、乘法和除法,請繼續(xù)完善Rational類,實(shí)現(xiàn)四則運(yùn)算。
#?coding=utf-8 #?有理遞歸數(shù)化簡: def?gcb(a,?b): ????if?b?==?0: ????????return?a ????return?gcb(b,?a?%?b) #?有理數(shù)p/q class?Rational(object): ????def?__init__(self,?p,?q): ????????self.p?=?p ????????self.q?=?q ???? ????#?有理數(shù)加法: ????def?__add__(self,?r): ????????return?Rational(self.p?*?r.q?+?self.q?*?r.p,?self.q?*?r.q) ???????? ????#?有理數(shù)減法: ????def?__sub__(self,?r): ????????return?Rational(self.p?*?r.q?-?r.p?*?self.q,?self.q?*?r.q) ???? ????#?有理數(shù)乘法: ????def?__mul__(self,?r): ????????return?Rational(self.p?*?r.p,?self.q?*?r.q) ???? ????#?有理數(shù)除法:(除以一個數(shù),等于乘它的倒數(shù)) ????#?def?__truediv__(self,?r): ????def??__div__(self,??r): ????????return?Rational(self.p?*?r.q,?self.q?*?r.p) ???????? ????#?有理數(shù)格式化輸出: ????def?__str__(self): ????????g?=?gcb(self.p,?self.q) ????????return?'{}/{}'.format(int(self.p/g),?int(self.q/g)) r1?=?Rational(1,?2) r2?=?Rational(1,?5) print(r1?+?r2) print(r1?-?r2) print(r1?*?r2) print(r1?/?r2)
? ??
查看全部 -
對于列表List或者元組Tuple,通過內(nèi)建方法len(),可以得出列表或者元組中元素的個數(shù)。如果一個類表現(xiàn)得像一個list,想使用len()函數(shù)來獲取元素個數(shù)時,則需要實(shí)現(xiàn)__len__()方法。
通過自定義__len__()方法,可以讓len()函數(shù)返回相關(guān)的結(jié)果,如果沒有定義__len__()方法的類使用len()函數(shù)獲取長度時,將會引起異常。
任務(wù):
# 斐波那契數(shù)列是由 0, 1, 1, 2, 3, 5, 8...構(gòu)成。
請編寫一個Fib類,F(xiàn)ib(10)表示數(shù)列的前10個元素,print Fib(10) 可以打印出數(shù)列的前 10 個元素,len(Fib(10))可以正確返回數(shù)列的個數(shù)10。
#?coding=utf-8 class?Fib(object): ????def?__init__(self,?num): ????????self.num?=?num ????????self.fibs?=?[] ????????a?=?0 ????????b?=?1 ????????for?i?in?range(num): ????????????self.fibs.append(a) ????????????a,?b?=?b,?a?+?b ????????????#?此句等同于: ????????????#?a?=?b? ????????????#?b?=?a+b ???? ????def?__str__(self): ????????return?str(self.fibs) ???? ????def?__len__(self): ????????return?self.num fibs?=?Fib(10) print(fibs) num?=?len(fibs) print(num)
查看全部
舉報