如何解决Python - 如何从派生类更新基类变量
我是 OOP 的新手,但在 SQL 方面有经验。我正在编写 Luigi ETL 任务来生成报告。
我有一个叫Report的基类,还有3个子类Report_Daily、Report_Weekly & Report_Monthly,它们动态设置基类的SQL查询的GROUP BY,以便生成合适的报表
#reports.py
class Report:
report_sql = {'daily':'day','weekly':'firstdayofweek(day)','monthly':'firstdayofmonth(day)'}
@property
def report_type(self):
return '' # To be instantiated by subclass
sql = 'select '+report_sql[report_type]+' count(*) from employees group by '+report_sql[report_type]
def run(self):
#code that runs sql query
class ReportDaily(Report):
report_type = 'Daily'
class ReportWeekly(Report):
report_type = 'Weekly'
class ReportMonthly(Report):
report_type = 'Monthly'
然后通过 Luigi & Chronos 安排这 3 个子类
luigi --module etl.reports ReportDaily
luigi --module etl.reports ReportWeekly
luigi --module etl.reports ReportMonthly
但我收到“无法连接字符串和属性”错误。
我尝试将 report_type 设置为 luigi 参数,但得到类似的错误。
实现这一目标的正确设计模式是什么?
解决方法
在 Python 中,如果你这样做:
package mainBoard;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class SetSquaresToClickable {
InitializeBoard initializeBoard=new InitializeBoard(); //different class accessed in this class to access components(i.e squares)
JPanel[][] squares=initializeBoard.getSquares();
SetSquaresToClickable() {
for(int i=0;i<8;i++) {
for(int j=0;j<8;j++) {
if(squares[i][j].contains(new JLabel)) { //checks if square contains a piece(does not work)
squares[i][j].addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
squares[i][j].setBackground(Color.BLUE); //sets square color to blue on being clicked if square contains piece.
}
});
}
}
}
}
public static void main(String[] args) {
new SetSquaresToClickable();
}
}
class Report:
report_sql = "bla"
将是一个类变量。 Python docs (Class and Instance Variables) 中的更多信息。因为你想在你的类中改变它,最好是一个实例变量(每个实例都是唯一的)。
另外,我认为 report_sql
类需要是一个抽象基类 (ABC)。查看文档了解更多信息:abc — Abstract Base Classes。因为从技术上讲,不应实例化抽象类,所以我的 Report
方法具有 __init__
装饰器。如您所见,abstractmethod
、ReportDaily
和 ReportWeekly
类使用所需的 ReportMonthly
调用基类的构造函数。
我只保留与报表类型和 SQL 查询相关的部分。这是我的新代码:
report_type
输出:
from abc import ABC,abstractmethod
class Report(ABC):
@abstractmethod
def __init__(self,report_type):
self.report_type = report_type
self.sql = f'select {self.report_type} count(*) ' \
f'from employees ' \
f'group by {self.report_type}'
def run(self):
...
class ReportDaily(Report):
def __init__(self):
super().__init__(report_type='Daily')
class ReportWeekly(Report):
def __init__(self):
super().__init__(report_type='Weekly')
class ReportMonthly(Report):
def __init__(self):
super().__init__(report_type='Monthly')
daily_report = ReportDaily()
print(daily_report.sql)
weekly_report = ReportWeekly()
print(weekly_report.sql)
monthly_report = ReportMonthly()
print(monthly_report.sql)
try:
Report(report_type="dummy")
except TypeError:
print("an abstract class cannot be instantiated!")
注意事项:
- 我使用 f-strings 进行字符串格式化。
- SQL Alchemy 是一个很好的 Python 处理 SQL 库
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。