【问题标题】:Python: make class method globalPython:使类方法全局化
【发布时间】:2017-08-21 12:41:01
【问题描述】:

有两个模块: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 是一个类的方法。

如果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 呢?我怎样才能创建实例,并且它的方法像以前的例子一样使用?除了将其作为参数传递或在每个函数中创建另一个解决方案之外,还有其他解决方案吗?

【问题讨论】:

  • 这是 class 方法还是 instance 方法?因为您似乎是在实例上调用它。
  • 实例方法。抱歉,我一点也不擅长术语和 OOP

标签: python class module arguments python-import


【解决方案1】:

正如 cmets 所说,如果您希望 my_func 表现得像全局函数但作为类中的方法,那么它应该是静态方法或类方法。这是一个例子——这是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 中的第一类对象。 从 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 的新模型,但老实说,我会说进行一些重构并不是什么大不了的事。

【讨论】:

  • 我刚刚看到应该是实例方法..我会尝试更新
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-18
  • 2016-10-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多