在Python中只允许函数作为方法调用
假设我正在编写一个模块MyPyLib,它使用另一个内置模块。从内置模块中,我导入了一个类Foo。然后我定义这个函数,bar:在Python中只允许函数作为方法调用,python,python-3.x,module,namespaces,Python,Python 3.x,Module,Namespaces,假设我正在编写一个模块MyPyLib,它使用另一个内置模块。从内置模块中,我导入了一个类Foo。然后我定义这个函数,bar: def bar(self): return self 这个函数是作为Foo类的方法编写的,我可以使用setattr(Foo,'bar',bar)使它正常工作。然后Foo.bar()将按预期工作。但是,任何导入MyPyLib的人也可以调用bar作为自己的函数。是否有任何方法限制此函数,使Foo.bar()工作,但bar(arg)不工作?您的代码不应该关心不正确的使
def bar(self):
return self
这个函数是作为Foo类的方法编写的,我可以使用
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
无法检测它是否被作为绑定方法调用或未绑定使用。另一种(更常见的)方法是从类Foo
派生一个新类,并将bar
明确定义为新类的方法:
class FooBar(Foo):
def bar(self):
return self
这样一来,
bar
的预期用途就更加明确了。就足够了。不管怎样,iInstance都会有帮助。我不相信这会产生预期的效果。您必须调用FooBar.bar()
,而不是Foo.bar()
,对吗?是的,您是对的。然而,您的注释似乎表明您不能使用子类FooBar
来代替原始类Foo
。如果是这种情况,那么您必须按照Martijn Pieters的建议使用猴子补丁。