Python 返回变量与分配属性

Python 返回变量与分配属性,python,class,object,attributes,Python,Class,Object,Attributes,我从未得到过正式的OOP指令,只是在python的基础知识上有点磕磕绊绊,但我正处于十字路口。 在处理实例化的类对象时,是通过方法分配属性更好,还是让方法只返回值更好?我读过很多关于不让对象的状态失控的书,但是我想不出最好的方法。下面是一个简单的例子: import magic class Histogram(): def __init__(self,directory): self.directory = directory # Data Option 1

我从未得到过正式的OOP指令,只是在python的基础知识上有点磕磕绊绊,但我正处于十字路口。 在处理实例化的类对象时,是通过方法分配属性更好,还是让方法只返回值更好?我读过很多关于不让对象的状态失控的书,但是我想不出最好的方法。下面是一个简单的例子:

import magic
class Histogram():
    def __init__(self,directory):
        self.directory = directory

    # Data Option 1
    def read_data(self):
         data = []
         file_ref = open(self.directory,'r')
         line = file_ref.readline()
         while line:
             data.append(line)
             line = file_ref.readline()
         return data

    # Data Option 2
    def set_data(self):
         data = []
         file_ref = open(self.directory,'r')
         line = file_ref.readline()
         while line:
             data.append(line)
             line = file_ref.readline()
         self.data = data



    # Hist Option 1
    def build_histogram(self):
        data = self.read_data()

        # It's not important what magic.histogram does.
        self.histogram = magic.histogram(data)

    # Hist Option 2
    def get_histogram(self,data):
        return magic.histogram(data)

    # Hist Option 3 - this requires self.get_data() to have already run.
    def build_histogram_2(self):
        self.histogram = magic.histogram(self.data)
因此,数据选项1强制用户调用该选项并将其存储在某个位置以与Hist选项2一起使用,或者将其存储在self.Data中以与Hist选项3一起使用。 数据选项2允许您使用Hist选项3,但您仍然必须运行set_数据

所以我真正的问题是,对于一个有方法做不同事情的类,通常可以但不必链接在一起,我应该如何编写它?隐式设置属性并有可能使状态混乱?返回变量并让“用户”设置它们?为我的方法使用的属性设置getter,如果属性不存在,如何处理


如果您需要更好的解释,或其他示例或任何内容,请告诉我。

我认为如果该值可能被许多方法使用,您最好将其设置为实例化(init)。如果您需要在每次使用它时进行计算,那么您不需要它是一个属性(只是一个变量),而应该在使用它时进行计算


最后,我要做的是避免我的对象像一个状态机,因为你不知道你已经计算了什么值,所以你不知道什么方法可以调用,什么方法不能调用。该数据是否合理地属于对象本身

在这种情况下,我会说是的。您的数据选项2正在加载合理地“属于”直方图对象的数据——尽管有理由认为构造函数应该只加载它,而不需要单独的方法调用来完成这一点


另外,如果你走另一条路,这不是一个真正的目标;您只是使用对象框架来收集一些相关的子例程。

我认为没有一个简单的答案。这完全取决于你想做什么,这是主观的。这正是我所期望的,因为我一直在反复思考我想如何处理它:(但也就是说,这些方法中的任何一种都不好吗?比如隐式要求一个方法运行,以便另一个方法能够实际使用第一个方法的结果?在其他条件相同的情况下,选项1有一些优点,比如可读性和易测试性。我肯定会避免选项3,而更喜欢选项1。在作为一个类,我更喜欢在
\uuuu init\uuuu
中设置所有参数,即使它使用
None
,这样您就可以一次看到所有属性。