<p>(下面,我保留了嵌套的类结构。但是请注意,只要将<code>Counter</code>class属性指定给所需的类,就可以在book类之外使用您喜欢的任何名称轻松地定义类本身。)</p>
<hr/>
<p>将如何实例化<code>Counter</code>类的知识从<code>__init__</code>中分离出来,并将其放入类方法中</p>
<pre><code>class BaseBookInfo:
class Counter:
def __init__(self, *, df, **kwargs):
super().__init__(**kwargs)
self.df = df
self.total = len(self.df)
self.status = self.count_status()
def count_status(self):
return self.df['status'].value_counts()
def __init__(self, *, counter, **kwargs):
super.__init__(**kwargs)
self.counter = counter
@classmethod
def from_dataframe(cls, df, **kwargs):
c = cls.Counter(df=df, **kwargs)
return cls(counter=c)
</code></pre>
<p>现在,调用方负责确保<code>Counter</code>被正确实例化,或者手动实例化</p>
<pre><code>b = BaseBookInfo(counter=BaseBookInfo.Counter(df))
</code></pre>
<p>或者通过专用的构造函数</p>
<pre><code>b = BaseBookInfo.from_dataframe(df=df)
</code></pre>
<p>当您将<code>BaseBookInfo</code>子类化时,不需要为<code>__init__</code>或<code>from_dataframe</code>提供新的定义;它们已经足够通用,可以处理您定义的任何类属性<code>Counter</code></p>
<pre><code>class BorrowedBook(BaseBookInfo):
class Counter(BaseBookInfo.Counter):
# These are Counter attributes, not BorrowedBook attributes
ZERO_BORROW = 'no borrowed books'
DELAY_EXIST = 'there are delayed books!!'
NO_PROBLEM = 'there is no problem!!'
def __init__(self, *, st_type, **kwargs):
super().__init__(**kwargs)
self.types = st_type
def show_status(self):
is_delayed = self.status['good'] != self.total
if not self.total:
result = self.ZERO_BORROW
elif is_delayed:
result = self.DELAY_EXIST
else:
result = self.NO_PROBLEM
print(result)
bb1 = BorrowedBook(counter=BorrowedBook.Counter(df=df, st_type=stat))
bb2 = BorrowedBook.from_dataframe(df, st_type=stat)
</code></pre>
<p>在<code>bb2</code>的情况下,<code>BorrowedBook</code>是继承的<code>from_dataframe</code>类方法的<code>cls</code>参数,因此将实例化正确的<code>Counter</code></p>