轉(zhuǎn)自:

創(chuàng)新互聯(lián)主要從事網(wǎng)站設(shè)計(jì)制作、做網(wǎng)站、網(wǎng)頁(yè)設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)山城,十年網(wǎng)站建設(shè)經(jīng)驗(yàn),價(jià)格優(yōu)惠、服務(wù)專業(yè),歡迎來(lái)電咨詢建站服務(wù):13518219792
本文實(shí)例講述了python實(shí)現(xiàn)支持目錄FTP上傳下載文件的方法。分享給大家供大家參考。具體如下:
該程序支持ftp上傳下載文件和目錄、適用于windows和linux平臺(tái)。
#!/usr/bin/env?python
#?-*-?coding:?utf-8?-*-
import?ftplib
import?os
import?sys
class?FTPSync(object):
conn?=?ftplib.FTP()
def?__init__(self,host,port=21):????
self.conn.connect(host,port)????
def?login(self,username,password):
self.conn.login(username,password)
self.conn.set_pasv(False)
print?self.conn.welcome
def?test(self,ftp_path):
print?ftp_path
print?self._is_ftp_dir(ftp_path)
#print?self.conn.nlst(ftp_path)
#self.conn.retrlines(?'LIST?./a/b')
#ftp_parent_path?=?os.path.dirname(ftp_path)
#ftp_dir_name?=?os.path.basename(ftp_path)
#print?ftp_parent_path
#print?ftp_dir_name
def?_is_ftp_file(self,ftp_path):
try:
if?ftp_path?in?self.conn.nlst(os.path.dirname(ftp_path)):
return?True
else:
return?False
except?ftplib.error_perm,e:
return?False
def?_ftp_list(self,?line):
list?=?line.split('?')
if?self.ftp_dir_name==list[-1]?and?list[0].startswith('d'):
self._is_dir?=?True
def?_is_ftp_dir(self,ftp_path):
ftp_path?=?ftp_path.rstrip('/')
ftp_parent_path?=?os.path.dirname(ftp_path)
self.ftp_dir_name?=?os.path.basename(ftp_path)
self._is_dir?=?False
if?ftp_path?==?'.'?or?ftp_path==?'./'?or?ftp_path=='':
self._is_dir?=?True
else:
#this?ues?callback?function?,that?will?change?_is_dir?value
try:
self.conn.retrlines('LIST?%s'?%ftp_parent_path,self._ftp_list)
except?ftplib.error_perm,e:
return?self._is_dir????
return?self._is_dir
def?get_file(self,ftp_path,local_path='.'):
ftp_path?=?ftp_path.rstrip('/')
if?self._is_ftp_file(ftp_path):????
file_name?=?os.path.basename(ftp_path)
#如果本地路徑是目錄,下載文件到該目錄
if?os.path.isdir(local_path):
file_handler?=?open(os.path.join(local_path,file_name),?'wb'?)
self.conn.retrbinary("RETR?%s"?%(ftp_path),?file_handler.write)?
file_handler.close()
#如果本地路徑不是目錄,但上層目錄存在,則按照本地路徑的文件名作為下載的文件名稱
elif?os.path.isdir(os.path.dirname(local_path)):
file_handler?=?open(local_path,?'wb'?)
self.conn.retrbinary("RETR?%s"?%(ftp_path),?file_handler.write)?
file_handler.close()
#如果本地路徑不是目錄,且上層目錄不存在,則退出
else:
print?'EROOR:The?dir:%s?is?not?exist'?%os.path.dirname(local_path)
else:
print?'EROOR:The?ftp?file:%s?is?not?exist'?%ftp_path
def?put_file(self,local_path,ftp_path='.'):
ftp_path?=?ftp_path.rstrip('/')
if?os.path.isfile(?local_path?):???????????
file_handler?=?open(local_path,?"r")
local_file_name?=?os.path.basename(local_path)
#如果遠(yuǎn)程路徑是個(gè)目錄,則上傳文件到這個(gè)目錄,文件名不變
if?self._is_ftp_dir(ftp_path):
self.conn.storbinary('STOR?%s'%os.path.join(ftp_path,local_file_name),?file_handler)
#如果遠(yuǎn)程路徑的上層是個(gè)目錄,則上傳文件,文件名按照給定命名
elif?self._is_ftp_dir(os.path.dirname(ftp_path)):?
print?'STOR?%s'%ftp_path????????
self.conn.storbinary('STOR?%s'%ftp_path,?file_handler)
#如果遠(yuǎn)程路徑不是目錄,且上一層的目錄也不存在,則提示給定遠(yuǎn)程路徑錯(cuò)誤
else:????????
print?'EROOR:The?ftp?path:%s?is?error'?%ftp_path
file_handler.close()
else:
print?'ERROR:The?file:%s?is?not?exist'?%local_path
def?get_dir(self,ftp_path,local_path='.',begin=True):?
ftp_path?=?ftp_path.rstrip('/')
#當(dāng)ftp目錄存在時(shí)下載????
if?self._is_ftp_dir(ftp_path):
#如果下載到本地當(dāng)前目錄下,并創(chuàng)建目錄
#下載初始化:如果給定的本地路徑不存在需要?jiǎng)?chuàng)建,同時(shí)將ftp的目錄存放在給定的本地目錄下。
#ftp目錄下文件存放的路徑為local_path=local_path+os.path.basename(ftp_path)
#例如:將ftp文件夾a下載到本地的a/b目錄下,則ftp的a目錄下的文件將下載到本地的a/b/a目錄下
if?begin:
if?not?os.path.isdir(local_path):
os.makedirs(local_path)
local_path=os.path.join(local_path,os.path.basename(ftp_path))
#如果本地目錄不存在,則創(chuàng)建目錄
if?not?os.path.isdir(local_path):
os.makedirs(local_path)
#進(jìn)入ftp目錄,開(kāi)始遞歸查詢
self.conn.cwd(ftp_path)
ftp_files?=?self.conn.nlst()
for?file?in?ftp_files:
local_file?=?os.path.join(local_path,?file)
#如果file?ftp路徑是目錄則遞歸上傳目錄(不需要再進(jìn)行初始化begin的標(biāo)志修改為False)
#如果file?ftp路徑是文件則直接上傳文件
if?self._is_ftp_dir(file):
self.get_dir(file,local_file,False)
else:
self.get_file(file,local_file)
#如果當(dāng)前ftp目錄文件已經(jīng)遍歷完畢返回上一層目錄
self.conn.cwd(?".."?)
return
else:
print?'ERROR:The?dir:%s?is?not?exist'?%ftp_path
return
def?put_dir(self,local_path,ftp_path='.',begin=True):
ftp_path?=?ftp_path.rstrip('/')
#當(dāng)本地目錄存在時(shí)上傳
if?os.path.isdir(local_path):??????
#上傳初始化:如果給定的ftp路徑不存在需要?jiǎng)?chuàng)建,同時(shí)將本地的目錄存放在給定的ftp目錄下。
#本地目錄下文件存放的路徑為ftp_path=ftp_path+os.path.basename(local_path)
#例如:將本地文件夾a上傳到ftp的a/b目錄下,則本地a目錄下的文件將上傳的ftp的a/b/a目錄下
if?begin:????????
if?not?self._is_ftp_dir(ftp_path):
self.conn.mkd(ftp_path)
ftp_path=os.path.join(ftp_path,os.path.basename(local_path))??????????
#如果ftp路徑不是目錄,則創(chuàng)建目錄
if?not?self._is_ftp_dir(ftp_path):
self.conn.mkd(ftp_path)
#進(jìn)入本地目錄,開(kāi)始遞歸查詢
os.chdir(local_path)
local_files?=?os.listdir('.')
for?file?in?local_files:
#如果file本地路徑是目錄則遞歸上傳目錄(不需要再進(jìn)行初始化begin的標(biāo)志修改為False)
#如果file本地路徑是文件則直接上傳文件
if?os.path.isdir(file):??????????
ftp_path=os.path.join(ftp_path,file)
self.put_dir(file,ftp_path,False)
else:
self.put_file(file,ftp_path)
#如果當(dāng)前本地目錄文件已經(jīng)遍歷完畢返回上一層目錄
os.chdir(?".."?)
else:
print?'ERROR:The?dir:%s?is?not?exist'?%local_path
return
if?__name__?==?'__main__':
ftp?=?FTPSync('192.168.1.110')
('test','test')
#上傳文件,不重命名
#('111.txt','a/b')
#上傳文件,重命名
#('111.txt','a/112.txt')
#下載文件,不重命名
#('/a/111.txt',r'D:\\')
#下載文件,重命名
#('/a/111.txt',r'D:\112.txt')
#下載到已經(jīng)存在的文件夾
#('a/b/c',r'D:\\a')
#下載到不存在的文件夾
#('a/b/c',r'D:\\aa')
#上傳到已經(jīng)存在的文件夾
('b','a')
#上傳到不存在的文件夾
('b','aa/B/')
希望本文所述對(duì)大家的Python程序設(shè)計(jì)有所幫助。
以下轉(zhuǎn)自:
Python中的ftplib模塊
Python中默認(rèn)安裝的ftplib模塊定義了FTP類,其中函數(shù)有限,可用來(lái)實(shí)現(xiàn)簡(jiǎn)單的ftp客戶端,用于上傳或下載文件
FTP的工作流程及基本操作可參考協(xié)議RFC959
ftp登陸連接
from ftplib import FTP #加載ftp模塊
ftp=FTP() #設(shè)置變量
#打開(kāi)調(diào)試級(jí)別2,顯示詳細(xì)信息
("IP","port") #連接的ftp sever和端口
("user","password")#連接的用戶名,密碼
print #打印出歡迎信息
("xxx/xxx") #更改遠(yuǎn)程目錄
bufsize=1024 #設(shè)置的緩沖區(qū)大小
filename="filename.txt" #需要下載的文件
file_handle=open(filename,"wb").write #以寫模式在本地打開(kāi)文件
("RETR filename.txt",file_handle,bufsize) #接收服務(wù)器上文件并寫入本地文件
#關(guān)閉調(diào)試模式
#退出ftp
ftp相關(guān)命令操作
#設(shè)置FTP當(dāng)前操作的路徑
#顯示目錄下文件信息
#獲取目錄下的文件
#新建遠(yuǎn)程目錄
#返回當(dāng)前所在位置
#刪除遠(yuǎn)程目錄
#刪除遠(yuǎn)程文件
(fromname, toname)#將fromname修改名稱為toname。
("STOR filename.txt",file_handel,bufsize) #上傳目標(biāo)文件
("RETR filename.txt",file_handel,bufsize)#下載FTP文件
網(wǎng)上找到一個(gè)具體的例子:
#?例:FTP編程??
from?ftplib?import?FTP??
ftp?=?FTP()??
timeout?=?30??
port?=?21??
('192.168.1.188',port,timeout)?#?連接FTP服務(wù)器??
('UserName','888888')?#?登錄??
print???#?獲得歡迎信息???
('file/test')????#?設(shè)置FTP路徑??
list?=????????#?獲得目錄列表??
for?name?in?list:??
print(name)?????????????#?打印文件名字??
path?=?'d:/data/'?+?name????#?文件保存路徑??
f?=?open(path,'wb')?????????#?打開(kāi)要保存文件??
filename?=?'RETR?'?+?name???#?保存FTP文件??
#?保存FTP上的文件??
#?刪除FTP文件??
('STOR?'+filename,?open(path,?'rb'))?#?上傳FTP文件??
#?退出FTP服務(wù)器
完整的模板:
#!/usr/bin/python??
#?-*-?coding:?utf-8?-*-??
import?ftplib??
import?os??
import?socket??
HOST?=?''??
DIRN?=?'pub/mozilla.org/webtools'??
FILE?=?'bugzilla-3.6.7.tar.gz'??
def?main():??
try:??
f?=?ftplib.FTP(HOST)??
except?(socket.error,?socket.gaierror):??
print?'ERROR:cannot?reach?"?%s"'?%?HOST??
return??
print?'***Connected?to?host?"%s"'?%?HOST??
try:??
f.login()??
except?ftplib.error_perm:??
print?'ERROR:?cannot?login?anonymously'??
f.quit()??
return??
print?'***?Logged?in?as?"anonymously"'??
try:??
f.cwd(DIRN)??
except?ftplib.error_perm:??
print?'ERRORL?cannot?CD?to?"%s"'?%?DIRN??
f.quit()??
return??
print?'***?Changed?to?"%s"?folder'?%?DIRN??
try:??
#傳一個(gè)回調(diào)函數(shù)給retrbinary()?它在每接收一個(gè)二進(jìn)制數(shù)據(jù)時(shí)都會(huì)被調(diào)用??
f.retrbinary('RETR?%s'?%?FILE,?open(FILE,?'wb').write)??
except?ftplib.error_perm:??
print?'ERROR:?cannot?read?file?"%s"'?%?FILE??
os.unlink(FILE)??
else:??
print?'***?Downloaded?"%s"?to?CWD'?%?FILE??
f.quit()??
return??
if?__name__?==?'__main__':??
main()
測(cè)試函數(shù)是用于自動(dòng)化測(cè)試,使用python模塊中的unittest中的工具來(lái)測(cè)試
附上書中摘抄來(lái)的代碼:
#coding=utf-8import unittestfrom name_function import get_formatted_nameclass NamesTestCase(unittest.TestCase): def test_first_last_name(self): formatted_name=get_formatted_name('janis','joplin') self.assertEqual(formatted_name,'Janis Joplin') def test_first_last_middle_name(self): formatted_name=get_formatted_name('wolfgang','mozart','amadeus') self.assertEqual(formatted_name,'Wolfgang Amadeus Mozart')#注意下面這行代碼,不寫會(huì)報(bào)錯(cuò)哦~~~書中沒(méi)有這行if __name__=="__main__": unittest.main()
Python在命令行定義函數(shù)的方法如下:
打開(kāi)電腦運(yùn)行窗體,輸入cmd,點(diǎn)擊確定
命令行窗口,輸入python,進(jìn)入python命令行,編寫函數(shù)后,敲兩次回車,即定義好了函數(shù)
測(cè)試函數(shù)可以正常使用
更多Python相關(guān)技術(shù)文章,請(qǐng)?jiān)L問(wèn)Python教程欄目進(jìn)行學(xué)習(xí)!以上就是小編分享的關(guān)于python如何在命令行定義函數(shù)的詳細(xì)內(nèi)容希望對(duì)大家有所幫助,更多有關(guān)python教程請(qǐng)關(guān)注環(huán)球青藤其它相關(guān)文章!
用open,該函數(shù)創(chuàng)建一個(gè)文件對(duì)象,這將用來(lái)調(diào)用與之關(guān)聯(lián)的其他支持方式即可:
file object = open(file_name [, access_mode][, buffering])
file_name: file_name參數(shù)是一個(gè)字符串值,包含要訪問(wèn)的文件的名稱。
access_mode: access_mode決定了文件必須被打開(kāi),即,讀,寫,追加等的可能值是下表中給定的一個(gè)完整的列表的模式。這是可選參數(shù),默認(rèn)文件存取方式為read (r)。
擴(kuò)展資料:
file命令的函數(shù)意義:
file 命令讀取用 File 參數(shù)或者 FileList 變量指定的文件,在每個(gè)文件上執(zhí)行一系列測(cè)試,然后將它們按照類型分類。然后此命令將文件類型寫入標(biāo)準(zhǔn)輸出。文件可以是常規(guī)文件、目錄、FIFO(指定的管道)、塊特殊文件、字符特別文件、符號(hào)鏈接或者套接字類型。
1、對(duì)于長(zhǎng)度為零的常規(guī)文件,將識(shí)別為空文件。
2、對(duì)于符號(hào)鏈接文件,缺省情況下此鏈接后跟符號(hào)鏈接引用的文件。
如果文件是 ASCII 碼的格式,則 file 命令將檢查前 1024 個(gè)字節(jié)然后確定文件類型。如果文件不是 ASCII 格式,則 file 命令將嘗試區(qū)分二進(jìn)制數(shù)據(jù)文件和包含擴(kuò)展字符的文本文件。
參考資料來(lái)源:百度百科-File
參考資料來(lái)源:百度百科-DriveName
1)doctest
使用doctest是一種類似于命令行嘗試的方式,用法很簡(jiǎn)單,如下
復(fù)制代碼代碼如下:
def f(n):
"""
f(1)
1
f(2)
2
"""
print(n)
if __name__ == '__main__':
import doctest
doctest.testmod()
應(yīng)該來(lái)說(shuō)是足夠簡(jiǎn)單了,另外還有一種方式doctest.testfile(filename),就是把命令行的方式放在文件里進(jìn)行測(cè)試。
2)unittest
unittest歷史悠久,最早可以追溯到上世紀(jì)七八十年代了,C++,Java里也都有類似的實(shí)現(xiàn),Python里的實(shí)現(xiàn)很簡(jiǎn)單。
unittest在python里主要的實(shí)現(xiàn)方式是TestCase,TestSuite。用法還是例子起步。
復(fù)制代碼代碼如下:
from widget import Widget
import unittest
# 執(zhí)行測(cè)試的類
class WidgetTestCase(unittest.TestCase):
def setUp(self):
self.widget = Widget()
def tearDown(self):
self.widget.dispose()
self.widget = None
def testSize(self):
self.assertEqual(self.widget.getSize(), (40, 40))
def testResize(self):
self.widget.resize(100, 100)
self.assertEqual(self.widget.getSize(), (100, 100))
# 測(cè)試
if __name__ == "__main__":
# 構(gòu)造測(cè)試集
suite = unittest.TestSuite()
suite.addTest(WidgetTestCase("testSize"))
suite.addTest(WidgetTestCase("testResize"))
# 執(zhí)行測(cè)試
runner = unittest.TextTestRunner()
runner.run(suite)
簡(jiǎn)單的說(shuō),1構(gòu)造TestCase(測(cè)試用例),其中的setup和teardown負(fù)責(zé)預(yù)處理和善后工作。2構(gòu)造測(cè)試集,添加用例3執(zhí)行測(cè)試需要說(shuō)明的是測(cè)試方法,在Python中有N多測(cè)試函數(shù),主要的有:
TestCase.assert_(expr[, msg])
TestCase.failUnless(expr[, msg])
TestCase.assertTrue(expr[, msg])
TestCase.assertEqual(first, second[, msg])
TestCase.failUnlessEqual(first, second[, msg])
TestCase.assertNotEqual(first, second[, msg])
TestCase.failIfEqual(first, second[, msg])
TestCase.assertAlmostEqual(first, second[, places[, msg]])
TestCase.failUnlessAlmostEqual(first, second[, places[, msg]])
TestCase.assertNotAlmostEqual(first, second[, places[, msg]])
TestCase.failIfAlmostEqual(first, second[, places[, msg]])
TestCase.assertRaises(exception, callable, ...)
TestCase.failUnlessRaises(exception, callable, ...)
TestCase.failIf(expr[, msg])
TestCase.assertFalse(expr[, msg])
TestCase.fail([msg])
def change(str1):
new_str = str()
for i in range(len(str1)):
if(65 = ord(str1[i]) = 90):
a = str1[i].lower()
print(a,end='')
elif(97 = ord(str1[i]) = 122):
a = str1[i].upper()
print(a,end='')
else:
a = str1[i]
print(a,end='')
return new_str
str2 = str(input("要轉(zhuǎn)換的字符串:"))
print(change(str2))
分享文章:包含python測(cè)試函數(shù)寫入的詞條
當(dāng)前地址:http://chinadenli.net/article0/dseppoo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供標(biāo)簽優(yōu)化、、ChatGPT、品牌網(wǎng)站制作、電子商務(wù)、網(wǎng)站導(dǎo)航
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)