在 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
的预期用途就更加清晰了。
假设我正在编写一个使用另一个内置模块的模块 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
的预期用途就更加清晰了。