我正在使用命令行界面,并希望在其中一个参数中使用multiprocessing
来选择核心用法。我试图解决的问题是,当用户没有调用-c
命令进行核心使用时,我想提示他并询问他是否要从默认的1
增加核心使用量。我面临的问题是,即使在我要求用户选择并使用parser.set_default
更改默认值之后,程序也会以1的核心使用率运行。使用parser.get_default
我可以看到默认值是用户选择的。但它似乎仍然只运行1核心。我没有粘贴所有代码,只有相关的部分。
修改
该程序是此脚本here
的略微修改版本parser.add_argument( "-o", "--specifycores", type = int,help= "Allows user to select number of cores for multiprocessing and faster uploads",default = 1 )
@contextlib.contextmanager
def multimap(cores=1):
if cores == 1:
if multiprocessing.cpu_count == 1:
cores = multiprocessing.cpu_count()
else:
print( 'You have {0} cores available.'.format( multiprocessing.cpu_count() ) )
while yes_no( 'Would you like to increase your core usage' ):
try:
cores = int( raw_input( 'Please enter the number or cores you wish to use: ') )
except ValueError:
print ( 'Please enter a valid number between 1 and {0}'.format( multiprocessing.cpu_count() ) )
else:
if cores > multiprocessing.cpu_count():
print ( 'Please enter a valid number between 1 and {0}'.format( multiprocessing.cpu_count() ) )
else:
parser.set_defaults(specifycores = cores)
break
cores = parser.get_default('specifycores')
print ( 'Uploading with {0} cores at {1}% usage'.format( cores, cores*100/multiprocessing.cpu_count() ) )
def wrapper(func):
def wrap(self, timeout=None):
return func(self, timeout=timeout if timeout is not None else 1e100)
return wrap
IMapIterator.next = wrapper(IMapIterator.next)
pool = multiprocessing.Pool(cores)
yield pool.imap
pool.terminate()
def _multipart_upload(bucket, s3_key_name, tarball, mb_size, use_rr=True,
cores=parser.get_default('specifycores')):
#some code
with multimap(cores) as pmap:
for _ in pmap(transfer_part, ( (mp.id, mp.key_name, mp.bucket_name, i, part)
for (i, part) in
enumerate( split_file ( tarball, mb_size, cores ) ) ) ):
pass
mp.complete_upload()
def main_for_multipupload(transfer_file, s3_key_name=None, use_rr=True,make_public=False, cores=1):
'''
Calls the _multipart_upload function and passes the required parameters to it
'''
#some code
mb_size = os.path.getsize(transfer_file) / 1e6
_multipart_upload(bucket, s3_key_name, transfer_file, mb_size, use_rr,
parser.get_default('specifycores'))
#main
try:
if args.specifycores > 1:
if multiprocessing.cpu_count() < args.specifycores:
main_for_multipupload( file_name, k.key, use_rr=True, make_public=False, cores=1)
else:
main_for_multipupload( file_name, k.key, use_rr=True, make_public=False, cores=args.specifycores)
else:
main_for_multipupload( file_name, k.key, use_rr=True, make_public=False, cores=parser.get_default('specifycores') )
end_time = timer()
print ( 'Time taken - {0} seconds'.format( str( int( end_time - start_time ) ) ) )
except Exception as e:
print e
答案 0 :(得分:1)
我没有检查过你的所有代码(与你明显的意图相反,你发布了很多不相关的代码)但是当你声明的意图没有默认值时你通过指定默认值显然使事情变得复杂(你的值是如果用户没有指定一个,则回退。
您不应指定默认值,也不应设置超出域范围的sentinel值;
parser.add_option(default = 0)
...
if value == 0:
value = input ("value: ")
对于必须是自然数的值,其他常见的无操作默认值为None
或-1;或者只是不设置默认值,并在未设置值时提示。