且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

为什么我不能将self作为命名参数传递给Python中的实例方法?

更新时间:2022-06-08 01:34:54

z.bar bound 方法-它已经具有im_self属性,该属性成为第一个参数(通常命名为self)到基础函数对象,即绑定方法的im_func属性.要覆盖它,显然您需要重新绑定im_self(编辑:或调用im_func)-无论您在参数传递方面做什么都不会对其产生任何影响, 当然.是的,这是 记录的方法绑定方法对象在Python中的工作方式(不仅仅是实现细节:每个正确的Python实现都必须完全采用这种方式).因此,从某种意义上说,这是使Python成为真正的语言的一部分,而不是稍微或完全不同的语言,这是必要的".当然,您可以设计一种不同的语言,选择按照完全不同的规则播放,但是-当然,它不是Python.

z.bar is a bound method -- it already has an im_self attribute that becomes the first argument (conventionally named self) to the underlying function object, the bound method's im_func attribute. To override that you obviously need to re-bind im_self (edit: or call the im_func instead) -- whatever you do in terms of argument passing is not going to have any effect on it, of course. Yep, that's the documented way bound methods object work in Python (not just an implementation detail: every correct Python implementation has to do it exactly this way). So it's "necessary" in the sense that it's part of what makes Python exactly the language it is, as opposed to being a slighty or strongly different language. Of course you could design a different language that chooses to play by completely different rules, but -- it wouldn't be Python, of course.

编辑:OP的编辑澄清了他是在调用 unbound 方法,而不是绑定方法.这仍然不起作用,并且从尝试得到的错误消息中清楚了原因:

Edit: the OP's edits clarified he's calling an unbound method, not a bound one. This still doesn't work, and the reason is clear from the error message the attempt gets:

TypeError:未绑定方法bar()必须 首先被Foo实例调用 争论(什么也不要做)

TypeError: unbound method bar() must be called with Foo instance as first argument (got nothing instead)

此非常清楚的错误消息所依据的规则是,实例必须是第一个参数(因此当然是位置参数:命名参数没有顺序). unbound方法不会知道"(也不在乎)该参数的 name 可能是什么(并且使用名称self只是它是一个惯例不是 Python语言的规则):它只关心第一个参数"的明确条件(当然还有位置参数).

The rule underlying this very clear error message is that the instance must be the first argument (so of course a positional one: named arguments have no ordering). The unbound method doesn't "know" (nor care) what that parameter's name may be (and the use of name self for it is only a convention, not a rule of the Python language): it only care about the unambiguous condition of "first argument" (among the positional ones, of course).

通过使未绑定的方法变得更加复杂,可以肯定地改变这种晦涩的极端情况(使用Python 3.2补丁,如果并且当语言更改的冻结"结束时;-):他们必须进行内省并保存第一个方法. -argument在创建时的名称,并在每次调用时检查关键字参数,以防有人通过名称而不是位置传递self的情况.我认为这不会破坏任何现有的有效代码,只会减慢每个现有的Python程序的速度.如果您编写并提出实现此复杂性的补丁程序,并积极使用python-dev来倡导它,以抗击肯定要面对的反对派风暴,那么毫无疑问,您有> 0的机会克服它-祝您好运

This obscure corner case could certainly be altered (with a Python 3.2 patch, if and when the language-changes "freeze" ends;-) by making unbound methods seriously more complicated: they'd have to introspect and save the first-argument's name at creation time, and check keyword arguments on each call just in case somebody's passing self by name instead of by position. I don't think this would break any existing, working code, it would only slow down just about every existing Python program. If you write and propose a patch implementing this complication, and get active on python-dev to advocate for it against the sure-to-come firestorm of opposition, you do no doubt stand a > 0 chance to ram it through -- good luck.

我们其余的人将继续获取im_func属性,这是元数据编程的一个非常荒谬的额外步骤,可以保证进行这种更改,这是一个非常荒谬的额外步骤,但这不是完全是特殊情况",与将命名参数传递给内置插件而又不采用命名参数(并且不暴露其参数名称"以轻松地将命名参数转换为位置参数(现在将是值得攻击的风车,恕我直言:在所有可调用函数中,内建函数对于元程序而言是最糟糕的!- ).

The rest of us, meanwhile, will keep getting the im_func attribute instead, as one absurdly-tiny extra step in what has to be a pretty complicated inded edifice of metaprogramming to warrant such a change -- it isn't a "special case" at all, compared with the horrid difficulties of adapting named-argument passing to builtins that don't take named arguments (and don't expose their "argument names" to easily allow the transformation of named arguments into positional ones (now that would be a windmill worth attacking, IMHO: of all callables, builtins are the worst to metaprogram about, because of that!-).