Python: 使 class 方法全局化

Python: make class method global

有两个模块:mainmy_module。还有一个函数 my_funcmy_module 导入并在整个主模块中使用,如

#main.py
from my_module import my_func

def main_func1():
    #do smth
    my_func()
    #do smth

def main_func2():
    #do smth
    my_func()
    #do smth

def main():
    #do smth
    main_func1()
    my_func()
    main_func2()
    #do smth

当我重写 my_module 中的代码时问题开始了,现在 my_func 是 class.

的一个方法

如果 my_func 仅在 main() 中,那么更改主模块会非常容易

from my_module import myClass

def main():
    c = myClass(init_parameters)
    #do smth
    main_func1()
    c.my_func()
    main_func2()
    #do smth

但是 main_func1main_func2 呢?我怎样才能使实例和它的方法像以前的例子一样使用?除了将其作为参数传递或在每个函数中创建另一个解决方案之外,还有其他解决方案吗?

正如评论所说,如果您希望 my_func 表现得像一个全局函数,但作为 class 中的一个方法,它应该是一个静态方法或 class 方法。这是一个示例 - 这是 foo.py:

的内容
class Foo:
    @staticmethod
    def say_hello():
        print("hello")

现在 main.py 你可以做:

from foo import Foo

say_hello = Foo.say_hello

def func1():
    say_hello()

def main():
    say_hello()
    func1()

if __name__ == "__main__":
    main()

这成功输出了

hello
hello

我使 say_hello 看起来像 main.py 中的全局函数的方法是在全局范围内将 Foo.say_hello 分配给 say_hello。这是完全可能的,因为函数是 Python 中的第一个 class 个对象。 从 foo 导入 Foo

考虑到它必须是一个实例方法:

class Foo:
    def __init__(self, msg):
        self.msg = msg

    def say(self):
        print(self.msg)

foo 模型不得不稍作改动。请记住,如果您希望它在调用它的实例上表现不同,那么它应该只是一个实例方法,因此在这种情况下,say 必须是一个实例方法,因为它依赖于 msg 值它的实例。

from foo import Foo

def func1():
    say()

def main():
    global say
    f = Foo("hello")
    say = f.say
    say()
    func1()

if __name__ == "__main__":
    main()

这仍然有效,尽管老实说,它现在的编码风格变得草率了。如果您的函数需要访问特定实例的方法,您应该将实例传递给它们。使用 global 关键字通常已经有点模糊了,我想说的是,当您将它用于实例方法时,这是双重事实。

from foo import Foo

def func1(f):
    f.say()

def main():
    f = Foo("hello")
    f.say()
    func1(f)

if __name__ == "__main__":
    main()

也很好用。您似乎有点担心必须更改代码才能与 my_func 的新模型一起使用,但老实说,我认为进行一些重构并不是什么大不了的事情。