【问题标题】:Functions in dictionaries in pythonpython中字典中的函数
【发布时间】:2018-06-26 21:57:54
【问题描述】:

我可以通过说将函数存储在字典中

MyDict = {}

def func():
    print("Hello, world!")

MyDict["func"] = func

我想知道是否有一种更简洁/更整洁的方式来写这个 - 类似于

MyDict = {}

def MyDict["func"]():
    print("Hello, world!")

但是这段代码会抛出语法错误

【问题讨论】:

  • 你考虑过使用类吗?
  • 我感觉这并不是你真正想要做的。您是否定义了如此不同的功能,以至于不能有一个共同的基础?
  • 从来没有用过一个类,谁能举例说明如何在这种情况下使用它。
  • 老实说,“最简洁”的编写方式是您的第一个代码块的编写方式。然而,这对我来说总体上是一个设计问题。
  • @the_constant 对于生产级代码,这肯定是一个设计问题,但对我来说,这个问题看起来不像那样。还回答诸如“我怎样才能使这项工作?”之类的问题。像“相信我,你不想知道答案”之类的东西不是很有帮助,我认为 OP 在了解更多有关 Python 后会自己达到这一点。 :)

标签: python function dictionary syntax


【解决方案1】:

你可以(ab)使用装饰器。

MyDict = {}

def store(d, name):
    def _(f):
        d[name] = f
        return f
    return _

@store(MyDict, "func")
def func():
    print("Hello, world!")

@store(MyDict, "foo")
def some_other_func():
    print("Goodbye")

如果您只想使用定义的名称作为键并对字典进行硬编码以进行更新,则可以简化此操作:

def store(f):
    MyDict[f.__name__] = f
    return f

@store
def func():
    print("Hello, world!")

【讨论】:

    【解决方案2】:

    对于您的示例,您可以这样做:

    d = {}
    d['func'] = lambda: print('Hello, world!')
    d['func']()
    >>> 'Hello, world!'
    

    如果你想使用一个类:

    class MyClass:
        def func(self):
            print('Hello, world!')
    
    c = MyClass()
    c.func()
    >>> 'Hello, world!'
    

    【讨论】:

    • 我倾向于不使用方法之间没有共享状态的类。
    • 当然,这些是函数字典的合理用例。不过,鉴于上下文,我怀疑这是最好的解决方案。如果您不同意我对问题的解释,请随意添加您自己的答案。
    • OP 显然是在初始请求中重新发明类,并且从未使用过它们。我认为最近几场比赛中的许多细微差别远远超出了 OP 目前的理解。
    • @MatthewStory 当没有提及任何状态,甚至没有任何需要访问控制/修改的建议时,我无法“清楚地”解释。
    • 课程适合我想要完成的工作,谢谢大家的帮助!
    【解决方案3】:

    这是错误的:

    def MyDict["func"]():
        print("Hello, world!")
    

    因为在def 之后你需要使用一些只包含allowed characters 的词。这就是你得到语法错误的原因。

    你可以使用的是:

    1) Lambda 函数(由@bphi 建议)

    MyDict = {}
    MyDict['func'] = lambda: print("123")
    MyDict['func']()
    

    2) Python class 使用setattr 内置函数动态创建存储在MyDict 中的方法(在类内部):

    def func1():
        print(1)
    
    
    def func2():
        print(2)
    
    
    MyDict = {}
    MyDict['func1'] = func1
    MyDict['func2'] = func2
    
    class MyClass3:
        def __init__(self):
            for name, obj in MyDict.items():
                setattr(self, name, obj)
    
    obj = MyClass3()
    obj.func1()
    obj.func2()
    

    或通过 lambda:

    MyDict = {}
    MyDict['func1'] = lambda : print(1)
    MyDict['func2'] = lambda : print(2)
    
    class MyClass3:
        def __init__(self):
            for name, obj in MyDict.items():
                setattr(self, name, obj)
    
    obj = MyClass3()
    obj.func1()
    obj.func2()
    

    class MyClass3:
        MyDict = {}
        MyDict['func1'] = lambda: print(1)
        MyDict['func2'] = lambda: print(2)
    
        def __init__(self):
            for name, obj in self.MyDict.items():
                setattr(self, name, obj)
    
    obj = MyClass3()
    obj.func1()
    obj.func2()
    

    【讨论】:

      【解决方案4】:

      如果您可以将所有功能表达为单行,请按照@bphi's answer 中的建议使用lambdas。

      如果您不想被 lambda 演算所限制,另一种方法是使用类及其静态方法。静态方法是类的方法,而不是类的实例,因此它们无法访问对象的内部状态,并且可以在类而不是实例上调用。

      但是,通过阅读此答案,您可能会明白为什么这不是一种非常优雅(或推荐)的方法,即使结果正是您所要求的。

      class MyClass:
          @staticmethod # this decorator is optional here, but suggested for code clarity
          def func():
              print("Hello, world!")
      
          def func2():
              print("Hey there, I am another function.")
      
      MyClass.func()
      >>> 'Hello, world!'
      MyClass.func()
      >>> 'Hey there, I am another function.'
      

      如果您想使用问题中建议的字典语法,可以在课堂上使用__dict__

      MyDict = dict(MyClass.__dict__)
      
      MyDict["func"]()
      >>> 'Hello, world!'
      MyDict["func2"]()
      >>> 'Hey there, I am another function.'
      

      您还可以在该字典中添加其他功能:

      MyDict["func3"] = lambda: print("Hi, I am yet another function.")
      
      def func4:
          print("And I am the last function for today.")
      
      MyDict["func4"] = func4
      
      MyDict["func"]()
      >>> 'Hi, I am yet another function.'
      MyDict["func2"]()
      >>> 'And I am the last function for today.'
      

      但由于这本字典只是类MyClass 的表示,它还包含一些与该类相关的项目,例如__weakref__。但是你可以提取自己的函数:

      MyCleanDict = {}
      for key, value in MyDict:
          if not key.startswith("_"):
              MyCleanDict[key] = value
      

      结果正是您所要求的,但我怀疑该方法的复杂性是否值得结果。我建议 a) 使用 lambda-functions,b) 保持第一种方法(首先定义函数,然后将它们放入 dict)或 c) 重新考虑您的实际问题,因为除了将函数存储在一本字典。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-10-06
        • 2022-11-25
        • 1970-01-01
        • 2021-07-15
        • 2016-06-26
        • 1970-01-01
        • 2015-05-28
        相关资源
        最近更新 更多