【问题标题】:TypeError: 'str' object is not callable in python scriptTypeError:'str'对象在python脚本中不可调用
【发布时间】:2017-04-21 18:26:42
【问题描述】:

是的,我是这个Change conditions using loop and array in python的作者

所以,我正在尝试改变条件:

if sys.argv[1] == 'add':
    sys.exit(add(db, usr))
if sys.argv[1] == 'rem':
    sys.exit(rem(db, usr))
if sys.argv[1] == 'rmusr':
    sys.exit(rmusr(db, usr))

我正在尝试使用循环更改列表中的这些条件

根据其他开发者的回答,我使用了这个:

actions = ['add','rem','rmusr']
if sys.argv[1] in actions:
    sys.exit(sys.argv[1](db, usr))

但是,当我尝试检查它的功能时,我有这个

  File "sql.py", line 25, in <module>
    sys.exit(sys.argv[1](db, usr))
TypeError: 'str' object is not callable

看不懂,哪里出错了?

【问题讨论】:

  • 他们在链接的问题中使用了字典,您使用的是列表
  • 因为我认为,该列表也应该有效,但我不明白,为什么它不起作用
  • 你有一个字符串列表而不是函数列表
  • 它不起作用的原因是您的数组是字符串列表,而不是函数。因此,当您执行sys.argv[1](db, usr) 时,实际上您实际上是在执行此操作:"rem"(db, usr)。解决方法是将字符串数组改为函数数组
  • 所以...只有字典?

标签: python arrays python-3.x for-loop if-statement


【解决方案1】:

您的错误具体是因为您尝试使用签名字符串(db,usr)调用方法。 sys.argv[1] 行指的是位于 program 系统中的 list argv 中的 string。字符串不可调用;您的代码相当于:

"add"(db, usr)  # add is not a variable name.

另一个问题的答案使用了一个字典,其查找键与同名的特定方法相关联,因此他们没有调用字符串,而是使用字符串从字典中查找方法。

【讨论】:

    【解决方案2】:

    为了调用sys.argv[1] 命名的函数,首先需要获取它。例如:

    def add(x,y):
        return x + y
    
    def mul(x,y):
        return x * y
    
    def perform(action, x, y):
        # action is a string containing a function name ("add" or "mul").
        # globals() contains the accessible members, along with the functions.
        return globals()[action](x, y)
    

    在原始代码的上下文中:

    actions = ['add','rem','rmusr']
    if sys.argv[1] in actions:
        func = globals()[sys.argv[1]]
        sys.exit(func(db, usr))
    

    【讨论】:

      【解决方案3】:

      sys.argv[1] 的类型为str(字符串),而字符串不是函数。因此,当您尝试执行sys.argv[1](db, usr) 时,您实际上是在尝试像执行函数一样执行字符串,这是不允许的。

      然而,您可以做的是通过使用sys.argv[1] 中的值来查找函数。您可以通过多种方式执行此操作。一种方法是使用globals() 查找函数,它返回映射到实际函数本身的函数名称的字典。

      例如:

      假设您使用以下命令执行程序:python myScript.py argument1。这意味着sys.argv[1] 的值将是"argument1"。然后,您将获取该值并在 globals() 返回的字典中查找该函数(或者,如果您与正在调用的函数在同一范围内,则可以使用 locals()):

      sys.exit(globals()[sys.argv[1]](db, usr))
      

      另一种方法是自己创建这个字典:

      actions = {'add': add, 'rem': rem, 'rmusr': rmusr}
      if sys.argv[1] in actions:
          sys.exit(actions[sys.argv[1]](db, usr))
      

      【讨论】:

      • actions 需要花括号 { } 来创建字典;它目前是一个列表(实际上,你会得到一个语法错误)。
      • 是的,我忘记改了。
      【解决方案4】:

      你可以使用这样的东西:

      # specify the function to call for each command:
      # (note: the lookup key is a string, but the value is a function reference)
      actions = {'add': add, 'rem': rem, 'rmusr': rmusr}
      cmd = sys.argv[1]
      # check if it's in the dictionary's keys
      if cmd in actions:
          # lookup the function to call
          func = actions[cmd]
          # call the function
          sys.exit(func(db, usr))
      

      或者这不那么冗长,但也不那么具体。它使用的事实是,所有定义的函数都按名称在globals() 字典中列出。

      # list of all allowed commands:
      actions = ['add', 'rem', 'rmusr']
      cmd = sys.argv[1]
      # check if it's allowed
      if cmd in actions:
          # lookup the function by name in the globals() dictionary
          func = globals()[cmd]
          # call the function
          sys.exit(func(db, usr))
      

      【讨论】:

        【解决方案5】:

        我更喜欢使用:https://docs.python.org/3.3/library/argparse.html 使用 argparse,您可以使用命令行 args 获得 morze 灵活性。如果在命令行中使用 arg,您可以轻松使用 if 语句。

        【讨论】:

          猜你喜欢
          • 2020-09-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-08-05
          • 2012-06-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多