[英]TypeError: It would appear that nargs is set to conflict with the composite type arity
I wrote this short little program as an effort to teach myself object oriented design in Python. 我写这个简短的小程序是为了在Python中自学面向对象设计。 But I am currently getting a very confusing error.
但我现在遇到一个非常令人困惑的错误。
Traceback (most recent call last):
File "main.py", line 97, in <module>
cli()
File "C:\Python27\lib\site-packages\click\core.py", line 716, in __call__
return self.main(*args, **kwargs)
File "C:\Python27\lib\site-packages\click\core.py", line 695, in main
with self.make_context(prog_name, args, **extra) as ctx:
File "C:\Python27\lib\site-packages\click\core.py", line 620, in make_context
self.parse_args(ctx, args)
File "C:\Python27\lib\site-packages\click\core.py", line 874, in parse_args
value, args = param.handle_parse_result(ctx, opts, args)
File "C:\Python27\lib\site-packages\click\core.py", line 1390, in handle_parse_result
value = self.full_process_value(ctx, value)
File "C:\Python27\lib\site-packages\click\core.py", line 1675, in full_process_value
return Parameter.full_process_value(self, ctx, value)
File "C:\Python27\lib\site-packages\click\core.py", line 1359, in full_process_value
value = self.process_value(ctx, value)
File "C:\Python27\lib\site-packages\click\core.py", line 1349, in process_value
return self.type_cast_value(ctx, value)
File "C:\Python27\lib\site-packages\click\core.py", line 1332, in type_cast_value
return self.type(value or (), self, ctx)
File "C:\Python27\lib\site-packages\click\types.py", line 38, in __call__
return self.convert(value, param, ctx)
File "C:\Python27\lib\site-packages\click\types.py", line 472, in convert
raise TypeError('It would appear that nargs is set to conflict '
TypeError: It would appear that nargs is set to conflict with the composite type arity.
This error is being raised by my click based CLI. 我的基于Click的CLI引发了此错误。 Which is odd because one of the options that is raising the error doesn't have any arguments.
这是奇怪的,因为引发错误的选项之一没有任何参数。
#-*- coding: utf-8 -*-
import click
import json
import glob
import os
def prompt(question):
val = raw_input(question + ' > ')
return val
def mkdir(path):
if not os.path.isdir(str(path)):
os.mkdir(str(path))
return str(path)
class Profile(object):
def __init__(self, name, age, weight, job, salary):
self.name = name
self.age = age
self.weight = weight
self.job = job
self.salary = salary
self.data = { 'name' : '',
'age' : '',
'weight' : '',
'job': '',
'salary' : ''
}
def new_profile(self, name, age, job, weight, salary, fname):
self.data['name'] = name
self.data['age'] = age
self.data['job'] = job
self.data['weight'] = weight
self.data['salary'] = salary
self.fname = fname
self.dirname = mkdir('.profiles\\')
with open(str(self.dirname) + str(self.fname) + '.json', 'w') as self.profile:
json.dump(self.data, self.profile)
print 'Profile saved!'
def list_profile(self):
print glob.glob('.profiles/*.json')
def print_profile(self, fname):
try:
self.fname = fname
with open('.profiles\\' + str(self.fname) + '.json') as data_file:
self.profile = json.load(data_file)
self.name = self.profile['name']
self.age = self.profile['age']
self.weight = self.profile['weight']
self.job = self.profile['job']
self.salary = self.profile['salary']
print 'name: {}\nage: {}\nweight: {}\noccupation: {}\nsalary: {}'.format(self.name, self.age, self.weight, self.job, self.salary)
except IOError:
print 'File not found'
@click.command(options_metavar='<options>')
@click.option('--new_profile', '-n',
nargs=6,
type=click.Tuple([str, str, str, str, str, str]),
metavar='<name, age, occupation, weight, salary, filename>',
help='Creates a new profile')
@click.option('--list_profile', '-l',
is_flag=True,
help='Lists all profiles that currently exist')
@click.option('--print_profile', '-p',
type=(str),
metavar='<profile name>',
help = 'prints data from a saved profile')
def cli(new_profile, list_profile, print_profile):
profile = Profile('', '', '', '', '')
if new_profile:
profile.new_profile(new_profile[0], new_profile[1], new_profile[2], new_profile[3], new_profile[4], new_profile[5]) # name, age, job, weight, salary, fname
elif list_profile:
profile.list_profile()
elif print_profile:
profile.print_profile(print_profile)
if __name__ == '__main__':
cli()
I have been struggling with this traceback for about a day now with no result. 我一直在努力与这个追溯大约一天现在没有结果。 Any suggestions?
有什么建议? Thanks!
谢谢!
EDIT: I sort of fixed it, but I created a logic error in the process. 编辑:我修复了它,但我在这个过程中创建了一个逻辑错误。
default=(None, None, None, None, None, None))
I added this argument to the click option new_profile. 我将此参数添加到click选项new_profile中。 But when you use any other argument it just runs
但是当你使用任何其他参数时它就会运行
Profile.new_profile(None, None None, None, None None)
thus creating a new file called none.json
in .profile
with all values being null. 从而在
.profile
创建一个名为none.json
的新文件,其中所有值都为null。 So I guess I technically solved THIS problem but I created an even bigger one. 所以我想我在技术上解决了这个问题,但我创造了一个更大的问题。
There are a couple of ways you can fix this. 有几种方法可以解决这个问题。
Do not use click.Tuple
不要使用
click.Tuple
Tuple
is intended for a multiple valued argument of non-uniform type. Tuple
用于非均匀类型的多值参数。 Since you are using 6 strings, this can be done more simply with: 由于您使用的是6个字符串,因此可以通过以下方式更简单地完成:
@click.option('--new_profile', '-n',
nargs=6,
type=str,
....
Use click.Tuple
with a default 使用具有默认值的
click.Tuple
As you discovered you can use a click.Tuple
if you specify a default. 正如您所发现的
click.Tuple
如果指定默认值,则可以使用click.Tuple
。
@click.option('--new_profile', '-n',
default=[None] * 6,
type=click.Tuple([str, str, str, str, str, str]),
....
Then you can qualify that you did not get the default like: 然后你可以证明你没有得到默认值:
if new_profile and None not in new_profile:
# create a new profile
....
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.