Python类方法-适当使用静态还是使用实例

时间:2018-10-24 13:06:03

标签: python

我正在尝试弄清如何组织许多对存储在python类实例中的数据进行迭代的代码。在大多数情况下,代码读取实例数据并产生一些结果(数字,列表等)。

从本质上讲,我只是在尝试通过创建顶级实例方法(将委婉的工作委派给需要实例数据的“笨拙”方法,但无需修改实例)的顶级实例方法来保持所有内容的可维护性和易读性。实例本身。

鉴于其他方法的只读性质,我是否最好将它们声明为静态方法,并将所需数据作为单独的参数传递,或者将它们全部保留为实例方法?

我更喜欢静态方法,因为“自我”参数表示该方法会修改实例数据,但我不知道我是否过度使用静态方法来采用该方法...

我意识到这引起了一个广泛的问题,需要基于意见的回应,但是我找不到任何信息表明过度使用静态方法会造成任何实际的困难/性能问题(反之亦然)。也就是说,我认为应该谨慎使用静态方法,但是我没有任何理由。

例如,在下面的代码片段中,假设静态方法表示对实例数据的重要操作,但它们是独立的,那么最好将它们标记为静态方法(这告诉我立即它们仅返回结果,而不是结果)修改实例或类),或使它们成为所有实例级方法并直接访问数据?这种方法会产生什么真正的问题吗?

class Test(object):

    def __init__(self):
        self.var1 = 10
        self.var2 = ["my", "list", "of", "strings"]
        self.var3 = [1,2,3,4,5]

    @staticmethod
    def processFloat(inst_float):
        pass

    @staticmethod
    def processList(inst_list):
        pass

    @staticmethod
    def processArray(inst_array):
        pass

    def doStuff(self):
        processFloat(self.var1)
        processList(self.var2)
        processArray(self.var3)

1 个答案:

答案 0 :(得分:1)

我认为您一定误解了self参数的使用。它用于引用您正在使用的类的实例。您必须使用实例方法访问实例数据(无论您是否进行修改),都无法使用静态方法获得数据*。

请考虑以下内容:

class Test(object):
    def __init__(self):
        self.my_instance_variable = 7

    def get_variable(self):
        return self.my_instance_variable

    @staticmethod
    def try_and_get_stuff():
        return self.my_instance_variable
        # This is not valid! "self" is undefined!
        # What other variable could we use here instead of self?
        # None! Because we don't have a reference to any instance!

a = Test()
# This is fine:
print(a.get_variable())
# This is fine too:
print(a.my_instance_variable)
# These are not fine:
print(Test.get_variable())
print(Test.my_instance_variable)
# Test has no variable called my_instance_variable until an instance of Test
# is instantiated!

现在,您可能想要编写与Test相关的某种辅助方法,而静态方法可能是放置它的好地方。但是您需要显式传递Test的实例才能处理:

class Test(object):
    def __init__(self, start_value):
        self.my_instance_variable = start_value

    def get_variable(self):
        return self.my_instance_variable

    @staticmethod
    def process_some_instances(list_of_test_instances):
        score = 0
        for my_test in list_of_test_instances:
            score = score + my_test.get_variable()
        return score

a = Test(8)
b = Test(9)
instance_list = [a, b]
print(Test.process_some_instances(instance_list)

您也可以只在模块级别将这些方法声明为函数。如果它们与特定的类相关,我通常更喜欢将它们作为静态或类方法放在类中这是个人喜好问题。如果您来自Java或类似的背景,那么您可能比模块级函数更容易理解静态方法。

(*,除非您在此问题的范围之外做了一些可怕的事情,否则您不应该在这里考虑)