简体   繁体   English

TypeError:看起来nargs设置为与复合类型arity冲突

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM