【问题标题】:Avoiding the reuse of a slow function in a Python class避免在 Python 类中重用慢速函数
【发布时间】:2019-03-16 12:48:26
【问题描述】:

假设我要创建一个 Python 类,其中一个函数输出需要用于其他几个函数,但这是一个非常缓慢的过程。有没有办法让这个输出成为其他函数使用的属性或全局变量,但不必重新运行慢速函数?

例如,下面的两个函数调用慢函数的类:

类测试类:

    def __init__(self, A):
            self.a = A

    def some_function(self):
            """ Function to show that the slow function feeds of another function first """
            a = self.a
            a*=2
            return a

    def slow_function(self): 
            """ Imagine this is a very slow function """
            test_value = self.some_function()
            test_value*=2
            return test_value

    def using_slow_function(self): 
            """ Calls the very slow function and then operates on the output """
            b = self.slow_function()
            b *=2
            return b

    def using_slow_function_again(self):
            """ Calls the very slow function and then operates on the output """
            c = self.slow_function()
            c *= 2
            return c

所以很明显,如果slow_function 说打开一个文件或一个缓慢的卷积过程,那么多次运行它将是一个很大的时间槽。

如果slow_function 的输出可以改为属性,那会有所帮助,但我不确定如何在课程中途执行此操作。

任何帮助将不胜感激!

【问题讨论】:

  • 当然。只需将输出设置为属性,而不是方法中的return
  • 在初始化中,设置self.long_function_result = None。使用任何其他方法时,您可以检查self.long_function_result是否不是None。如果是,请调用 long 函数并更新 self.long_function_result。如果不是None,只需获取值。方法不必返回任何东西,您可以使用它们来更新对象的状态

标签: python function class attributes


【解决方案1】:

您可以随时在已初始化的 python 对象中分配属性。

它们不必在初始化时完成,您甚至可以从对象外部分配它们。

>>> class A:
...     def __init__(self):
...         self.a = 1
...     def thing(self):
...         self.b = 2
... 
>>> c=A()
>>> c.a
1
>>> c.b
Traceback (most recent call last):
  module __main__ line 141
traceback.print_exc()
  module <module> line 1
c.b
AttributeError: 'A' object has no attribute 'b'
>>> c.thing()
>>> c.b
2
>>> c.c = 3
>>> c.c
3

编辑:根据@roganjosh 的评论,您可以在初始化期间将其分配为none。您不仅不会得到AttributeErrors,而且更容易跟踪所有属性。

>>> class A:
...     def __init__(self):
...         self.a = 1
...         self.b = None
...     def thing(self):
...         if self.b is None:
...             self.b = 2
... 
>>> c=A()
>>> c.b
None
>>> c.thing()
>>> c.b
2
>>> c.b = 3
>>> c.thing()
>>> c.b
3

【讨论】:

  • 是的,在对象创建后尽量不让属性出现肯定更好。它还允许您在对象的任何实例上调用 dir 并查看所有命名属性,而无需调用方法。
  • @roganjosh 如果您有一个对象,您只希望在调用特定方法后属性可用,我可以看到它的用途。不过很少见。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多