尽管我在使用Python方面有丰富的经验,但我发现有时很难确定是否应将相关的函数和属性放在类中。更具体地说,我有一个使用该类的属性的函数,以下函数顺序使用前一个函数的返回值。例如,功能1->功能2->功能3等等,每个功能都返回一些内容。
我想了解在这种情况下使用类是否有意义,因为这对我来说很常见。我想确保以合理且干净的方式创建对象(销售表)。
到目前为止,我只创建了一个带有一些属性和实例方法的简单类。我不确定我还能怎么做。我查找了有关Stacks,文章和许多其他资源的大量文章。我相信我对类的目的有相当的了解,但在适合使用它时却了解得很少。
需要明确的是,我并不是在寻求有关函数本身或其逻辑的帮助(尽管我感谢任何建议!)。我只想知道使用类是不是一种方法。我没有在函数中包含任何代码,因为我认为它们的逻辑与我的问题无关(如果需要,我可以添加!)
class SalesTable:
def __init__(self, banner, start_year, start_month, end_year, end_month):
"""These attributes act as filters when searching for the relevant data."""
self.banner = banner
self.start_year = start_year
self.start_month = start_month
if not end_year:
self.end_year = start_year
else:
self.end_year = end_year
if not end_month:
self.end_month = start_month
else:
self.end_month = end_month
def sales_periods(self):
"""Will create a dict with a key as the year and each year will have a list of months as the value. The
stated attributes are used ONLY here as filters to determine what years and months are included"""
pass
def find_sales_period_csv(self):
"""Using the dictionary returned from the function above, will search through the relevant directories and
subdirectories to find all the paths for individual csvs where the sales data is stored as determined by the
value in the dictionary and store the paths in a list"""
pass
def csv_to_df(self):
"""Using the list returned from the function above, will take each csv path in the list and convert them into a
dataframe and store those dateframes in another list"""
pass
def combine_dfs(self):
"""Using the list return from the function above, will concatenate all dfs into a single dataframe"""
def check_data(self):
"""Maybe do some checking here to ensure all relevant data concatenated properly (i.e total row count etc.)"""
理想情况下,我想通过函数序列之后的最后一个函数(combine_dfs)返回销售表。我可以很轻松地完成此任务,但是,我不确定这是否是构建脚本的最佳方法,或者尽管我希望它可以正常工作,但从逻辑上讲还是合理的。
答案 0 :(得分:1)
理想情况下,class
有两个主要用途:
1)为防止重复。如果您创建同一对象的次数超过了在一个类中创建的对象的次数。
2)将事物分组在一起。如果将所有相关功能和属性组合在一起,则读取某人的代码会容易得多。这也使可维护性和可移植性更加容易。
方法在类中相互调用是很常见的,因为理想情况下方法不应超过30行(尽管不同的组有不同的标准)。如果仅从类内调用方法,则该方法应为private
,并且应在该方法前附加__
(两个下划线)。
答案 1 :(得分:1)
由于只有sales_periods
实际上使用实例属性,并且它返回dict
,而不返回SalesTable
的另一个实例,因此所有其他方法都可以移出该类并定义为常规功能:
class SalesTable:
def __init__(self, banner, start_year, start_month, end_year, end_month):
...
def sales_periods(self):
# ...
return some_dict
def find_sales_period_csv(dct):
return some_list
def csv_to_df(lst):
return some_list
def combine_dfs(lst):
return some_df
def check_data(df):
pass
您将以链接的方式将它们全部命名:
x = SalesTable(...)
check_data(combine_dfs(csv_to_df(find_sales_period_csv(x.sales_periods()))))
现在仔细看一下您的类:您只有两种方法,__init__
和sales_periods
。除非__init__
进行了您不想重复的昂贵操作(并且您将在同一实例上多次调用sales_periods
),否则整个类可以简化为结合了{{1 }}和__init__
方法:
sales_period
答案 2 :(得分:0)
如果一堆数据和功能似乎并存在一起,也就是说您通常同时引用它们,那么您就有充分的理由认为自己手上可能有一个对象。
另一个很好的理由是该对象是否有自然名称。我知道很奇怪,但这确实是一个有用的指导原则。
阅读SOLID可能还会使您有所思考。
答案 3 :(得分:0)
OOP的新手往往会创建太多的类(我知道我一开始就是这样做的)。这样做的一个问题是代码的可读性:当代码使用自定义类时,通常有必要阅读类定义以弄清楚该类应该做什么。如果代码仅使用内置类型,则通常更容易弄清楚。而且,复杂的内部状态是类的自然特征,通常是一些细微错误的来源,并使代码更难以推理。
答案 4 :(得分:0)
This book很有帮助
上面的每个方法看起来都与类有关。因此,可以说您在类外部定义了许多函数,并且将相同的十个变量集作为参数传递给每个变量。那将表明他们应该在班上。访问和修改太多的变量并将它们作为参数传递给其他函数,而不是将其作为在每个方法中都被修改的类属性,这表明您没有利用类的优点之一。在那本书中,我记得有一节专门介绍了代码需要OOP的各种迹象。