如果我理解的正確的話,樓主是要copy大文件吧。
創(chuàng)新互聯(lián)是專業(yè)的小店網(wǎng)站建設(shè)公司,小店接單;提供網(wǎng)站制作、成都網(wǎng)站制作,網(wǎng)頁(yè)設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行小店網(wǎng)站開(kāi)發(fā)網(wǎng)頁(yè)制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛(ài)的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來(lái)合作!
python最經(jīng)常使用的copy函數(shù),應(yīng)該是shutil.copyfile()了,它默認(rèn)以16384bytes 的大小作為緩沖區(qū),對(duì)于小的文件,的確不錯(cuò)。但是處理到大的文件的時(shí)候,性能下降就很?chē)?yán)重。過(guò)小的buffer會(huì)不合適。
經(jīng)過(guò)多次的嘗試,發(fā)現(xiàn)10Mb的buffer最合適,再高也沒(méi)有性能的提升。重載后的copy函數(shù)如下
def?copyFile(src,?dst,?buffer_size=10485760,?perserveFileDate=True):
'''
Copies?a?file?to?a?new?location.?Much?faster?performance?than?Apache?Commons?due?to?use?of?larger?buffer
@param?src:????Source?File
@param?dst:????Destination?File?(not?file?path)
@param?buffer_size:????Buffer?size?to?use?during?copy
@param?perserveFileDate:????Preserve?the?original?file?date
'''
#????Check?to?make?sure?destination?directory?exists.?If?it?doesn't?create?the?directory
dstParent,?dstFileName?=?os.path.split(dst)
if(not(os.path.exists(dstParent))):
os.makedirs(dstParent)
#????Optimize?the?buffer?for?small?files
buffer_size?=?min(buffer_size,os.path.getsize(src))
if(buffer_size?==?0):
buffer_size?=?1024
if?shutil._samefile(src,?dst):
raise?shutil.Error("`%s`?and?`%s`?are?the?same?file"?%?(src,?dst))
for?fn?in?[src,?dst]:
try:
st?=?os.stat(fn)
except?OSError:
#?File?most?likely?does?not?exist
pass
else:
#?XXX?What?about?other?special?files??(sockets,?devices...)
if?shutil.stat.S_ISFIFO(st.st_mode):
raise?shutil.SpecialFileError("`%s`?is?a?named?pipe"?%?fn)
with?open(src,?'rb')?as?fsrc:
with?open(dst,?'wb')?as?fdst:
shutil.copyfileobj(fsrc,?fdst,?buffer_size)
if(perserveFileDate):
shutil.copystat(src,?dst)
使用的時(shí)候記得添加相應(yīng)的包。
如果是我,我會(huì)在函數(shù)里面聲明b是global的,而不是用似是而非的傳值傳指針,你這樣寫(xiě)是想說(shuō)b_hash傳遞的是指針,可惜python里一旦用“=”賦值就已經(jīng)相當(dāng)于聲明了一個(gè)新的變量,所以你的這個(gè)問(wèn)題兩種解決辦法:
第一個(gè),把你要傳指針的東西放到列表里:
def?test(aa,bb):
bb[0]=copy.deepcopy(aa)
a={1:1}
b=[{}]
test(a,b)
print?b[0]
這樣保證你可以通過(guò)b這個(gè)名字找到改變后的指針。
第二個(gè),在函數(shù)里聲明你要修改的是全局變量:
def?test(aa):
global?b
b=copy.deepcopy(aa)
a={1:1}
b={}
test(a)
print?b
當(dāng)然,你還可以用既不是global也不是local的局部作用域,那可以說(shuō)叫閉包,但有些不好懂就不說(shuō)了。。。
樓上的方法思想和第一種一樣,但是沒(méi)做深層拷貝,一層for循環(huán)沒(méi)有遞歸實(shí)現(xiàn)了copy.copy,而不是copy.deepcopy。。。
提問(wèn)者這么短的描述,有點(diǎn)無(wú)法看懂,那就按照通常的幾種方法來(lái)說(shuō)吧:
簡(jiǎn)單列表的拷貝
已知一個(gè)列表,求生成一個(gè)新的列表,列表元素是原列表的復(fù)制
a=[1,2]
b=a
這種其實(shí)并未真正生成一個(gè)新的列表,b指向的仍然是a所指向的對(duì)象。
后果:如果對(duì)a或b的元素進(jìn)行修改,a,b的值同時(shí)發(fā)生變化。
可以使用以下方法解決:
a=[1,2]
b=a[:]
這樣修改a對(duì)b沒(méi)有影響。修改b對(duì)a沒(méi)有影響。
復(fù)雜列表的拷貝:
可以使用copy模塊中的deepcopy函數(shù)。修改測(cè)試如下:
import copy
a=[1,[2]]
b=copy.deepcopy(a)