在 Python 中只让函数作为方法调用

Only let function be called as a method in Python

假设我正在编写一个使用另一个内置模块的模块 MyPyLib。从内置模块中,我导入了一个 class, Foo.然后我定义这个函数,bar:

def bar(self):
    return self

此函数被编写为 Foo class 的一个方法,我可以使它与 setattr(Foo,'bar', bar) 一起正常运行。然后 Foo.bar() 将按预期工作。但是,任何导入 MyPyLib 的人也可以调用 bar 作为自己的函数。有什么方法可以限制此功能,使 Foo.bar() 有效,但 bar(arg) 无效?

你的代码不应该关心不正确的使用,那是调用者的问题。 Python 是一种供 成年人同意的语言 ;如果有人想违反规则并使用 bar 和不同的论点,那是他们的问题,而不是你的问题。

如果您坚持,这里唯一的选择是显式测试 self 的类型:

def bar(self):
    assert isinstance(self, Foo)
    return self

因为 bar 无法检测到它是作为绑定方法调用还是未绑定使用。

另一种(也是更常用的)方法是从 class Foo 派生新的 class 并将 bar 明确定义为新 class:

class FooBar(Foo):
    def bar(self):
        return self

这样 bar 的预期用途就更加清晰了。