我有一个基类,里面有这样的类
import pandas as pd
book_df = pd.DataFrame(
{
'title': [f'title{num}' for num in range(5)],
'due date': pd.date_range(start='2021-07-26', periods=5, freq='D').to_list(),
'status': ['delay', 'delay', 'return', 'good', 'good']
})
class BaseBookInfo(object):
def __init__(self, df):
self.counter = self.Counter(df)
class Counter(object):
def __init__(self, df):
self.df = df
self.total = len(self.df)
self.status = self.count_status()
def count_status(self):
return self.df['status'].value_counts()
。。我创建了一个具有如下重写的子类
class BooksBorrowed(BaseBookInfo):
status_type = {
'ZERO_BORROW': 'no borrowed books',
'DELAY_EXIST': 'there are delayed books!!',
'NO_PROBLEM': 'there is no problem!!',
}
def __init_(self, df):
super().__init__(df)
self.counter = self.Counter(df, self.status_type)
class Counter(BaseBookInfo.Counter):
def __init__(self, df, st_type):
super().__init__(df)
self.types = st_type
def show_status(self):
is_delayed = self.status['good'] != self.total
if self.total:
if is_delayed:
result = 'DELAY_EXIST'
else:
result = 'NO_PROBLEM'
else:
result = 'ZERO_BORROW'
print(f'{self.types[result]}')
当我测试BooksBorrowed
时,我得到了这个错误
Traceback (most recent call last):
....
File "D:/repository/BillMaker/src/billmaker/scraper/test_stackoverflow.py", line 54, in <module>
bb = BooksBorrowed(book_df)
File "D:/repository/BillMaker/src/billmaker/scraper/test_stackoverflow.py", line 15, in __init__
self.counter = self.Counter(df)
TypeError: __init__() missing 1 required positional argument: 'st_type'
我希望来自子类的Counter
类的super().__init__()
调用将连接到基类的内部类,但我错了
你能告诉我在我的情况下什么是错误的想法吗
我不想更改BooksBorrowed.status_type
的位置,因为它也将在BookBorrowed
中使用
更新:
在问了这个问题之后,我开始阅读关于这个主题的文章。我发现我的示例与破坏Liskov substitution principle
的典型案例非常相似。此外,我开始知道什么是has a
关系,@simonCrowe已经在下面进行了评论。所以我现在明白了,这是一个更好的组合案例,而不是继承案例。谢谢你的评论
我引用了this book,发现我的代码违反了许多继承规则。 下面引用的所有区块部分都来自本书
我打破了继承的规则
BooksBorrowed.Counter
正在破坏substitutabiltiy
BooksBorrowed.Counter.__init__
使用不同数量的参数李>has-a
关系has a
“状态类型”。但是,status-type
是以继承方式重写的李>如何使用作文方式
这是我最后的代码,我觉得更好。如果您发现任何部分可以进一步改进,请回答我的问题,我将接受您的问题。我不想接受我的答案
(下面,我保留了嵌套的类结构。但是请注意,只要将
Counter
class属性指定给所需的类,就可以在book类之外使用您喜欢的任何名称轻松地定义类本身。)将如何实例化
Counter
类的知识从__init__
中分离出来,并将其放入类方法中现在,调用方负责确保
Counter
被正确实例化,或者手动实例化或者通过专用的构造函数
当您将
BaseBookInfo
子类化时,不需要为__init__
或from_dataframe
提供新的定义;它们已经足够通用,可以处理您定义的任何类属性Counter
在
bb2
的情况下,BorrowedBook
是继承的from_dataframe
类方法的cls
参数,因此将实例化正确的Counter
相关问题 更多 >
编程相关推荐