为了账号安全,请及时绑定邮箱和手机立即绑定

你可以在 python 类的 __init__ 中使用静态方法作为默认参数吗?

你可以在 python 类的 __init__ 中使用静态方法作为默认参数吗?

九州编程 2021-10-26 16:47:26
我正在为神经网络编写一个类,我想对其进行某种形式的定制,以便您可以选择不同的成本函数和正则化。为此,我想将它们设置为__init__()方法中的默认参数。但是当我传入MyClass.static_method我的示例时,解释器会告诉我 MyClass 还没有(还)定义。为什么会这样,是否有比我更好的解决方法?您当然可以将静态方法设置为默认参数,但随后会出现其他问题。例如,如果我想访问函数名称(我真正想要的),我不能立即使用__name__。我知道如何通过访问static_method.__func__.__name__. 但这似乎很笨拙,并且当您获得一个静态方法对象时,似乎不打算以这种方式使用它。class MyClass:    @staticmethod    def static_method():        do_something()    def __init__(self, func=MyClass.static_method, func2=static_method):        self.name = func.__name__                  #Does not work        self.name2 = func2.__func__.__name__       #Should work我确实希望MyClass.static_method工作,但该类当时似乎不存在。那么,最后一次,为什么?
查看完整描述

2 回答

?
holdtom

TA贡献1805条经验 获得超10个赞

您在将静态方法用作默认参数时遇到问题的原因是两个问题的组合。


第一个问题是,在def语句运行时需要很好地定义默认参数,而不仅仅是在调用函数时。那是因为默认参数被内置到函数对象中,而不是在每次函数运行时重新计算(这也是为什么像空列表这样的可变默认参数通常是错误的原因)。无论如何,这就是您不能MyClass.static_method用作默认参数的原因,因为MyClass在定义函数时尚未定义(类对象仅在其所有内容都已创建后生成)。


下一个问题是staticmethod对象不具有与常规函数相同的属性和方法。通常这无关紧要,因为当您通过类对象(例如,MyClass.static_method一旦MyClass存在)或通过实例(例如self.static_method)访问它时,它将是可调用的并且具有__name__. 但那是因为您在这些情况下获得了底层功能,而不是staticmethod对象本身。该staticmethod对象本身是一个描述符,而不是调用。


所以这两个函数都不能正常工作:


class MyClass:

    @staticmethod

    def static_method():

        pass


    def foo(self, func=MyClass.static_method): # won't work because MyClass doesn't exist yet

        pass


    def bar(self, func=static_method): # this declaration will work (if you comment out foo)

        name = func.__name__  # but this doesn't work when the bar() is called

        func()                # nor this, as func is the staticmethod object

什么工作将使用staticmethod对象底层的实际函数作为默认值:


    def baz(self, func=static_method.__func__):  # this works!

        name = func.__name__

        func()

与使用name = func.__func__.__name__.


查看完整回答
反对 回复 2021-10-26
  • 2 回答
  • 0 关注
  • 296 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信