繁体   English   中英

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

[英]TypeError: It would appear that nargs is set to conflict with the composite type arity

我写这个简短的小程序是为了在Python中自学面向对象设计。 但我现在遇到一个非常令人困惑的错误。

  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.

我的基于Click的CLI引发了此错误。 这是奇怪的,因为引发错误的选项之一没有任何参数。

#-*- 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()

我一直在努力与这个追溯大约一天现在没有结果。 有什么建议? 谢谢!

编辑:我修复了它,但我在这个过程中创建了一个逻辑错误。

default=(None, None, None, None, None, None))

我将此参数添加到click选项new_profile中。 但是当你使用任何其他参数时它就会运行

Profile.new_profile(None, None None, None, None None)

从而在.profile创建一个名为none.json的新文件,其中所有值都为null。 所以我想我在技术上解决了这个问题,但我创造了一个更大的问题。

有几种方法可以解决这个问题。

不要使用click.Tuple

Tuple用于非均匀类型的多值参数。 由于您使用的是6个字符串,因此可以通过以下方式更简单地完成:

@click.option('--new_profile', '-n',
              nargs=6,
              type=str,
              ....

使用具有默认值的click.Tuple

正如您所发现的click.Tuple如果指定默认值,则可以使用click.Tuple

@click.option('--new_profile', '-n',
              default=[None] * 6,
              type=click.Tuple([str, str, str, str, str, str]),
              ....

然后你可以证明你没有得到默认值:

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