Python 抽象方法默认逻辑,super() 方法
Python Abstract Method Default Logic, super() method
我来自 Java 世界,我很难理解与抽象方法相关的 super() 方法。
我有一个带有抽象方法的抽象 class。这个 class' 子 classes 负责查询我的 MySQL 数据库并向我返回格式化报告。在一半的子 class 中,他们使用与 运行 报告完全相同的逻辑。在另一半,每个人都需要自己的逻辑。因此我想使 run_report
成为一个抽象方法。
class Report:
__metaclass__ = ABCMeta
def __init__(self):
self.user = 'root'
self.passwd = ''
self.host = '127.0.0.0.1'
self.port = '80'
self.db = 'animals'
self.conn = mysql.connector.connect(user=self.user, password=self.passd, db=self.db, host=self.host, port=self.port)
self.cursor = self.conn.cursor()
@staticmethod
def construct_query(query, external_data):
finalQuery = query % external_data
return finalQuery
@abstractmethod
def run_report(self, query):
self.cursor.execute(self, query)
results = self.cursor.fetchall()
return data
这是一个 class 的实现示例,它按原样使用抽象方法:
class SheepReport(Report):
query = "SELECT COUNT(*) FROM sheep WHERE alive = 1;"
def run_report(query):
super(Report, self).run_report(query)
这个语法看起来很神秘。我的代码太不完整,目前无法测试 运行,我正在努力将错误消灭在萌芽状态。我对抽象方法的理解正确吗?
相比之下,这里有一个 class 覆盖了 run_report:
class CowReport(Report):
query = "SELECT height, weight FROM cows WHERE name IN (%s);"
def run_report(self):
finalQuery = self.construct_query(query, "'Hilda', 'Gary'");
self.cursor.execute(self, finalQuery)
results = self.cursor.fetchall()
return data
我走在正确的轨道上吗?我看到的所有 super() 和继承的例子都让我头疼,我想我需要有人为我简化它。
首先,我真诚地希望这只是为了学习目的,而不是实际的生产代码。将未经过滤的用户输入传递到查询字符串中等于完全成熟的 SQL injection attack.
除此之外...
抽象 classes 通常用于定义接口,而不是具体的功能。不管你想做什么,只有 query
定义为抽象 属性 的抽象 class 会大大简化你的代码。
class Report:
__metaclass__ = ABCMeta
def __init__(self):
self.user = 'root'
self.passwd = ''
self.host = '127.0.0.0.1'
self.port = '80'
self.db = 'animals'
self.conn = mysql.connector.connect(user=self.user, password=self.passd, db=self.db,
host=self.host, port=self.port)
self.cursor = self.conn.cursor()
@abstractproperty
def query(self):
return NotImplemented
def construct_query(self, **external_data):
finalQuery = self.query % external_data
return finalQuery
def run_report(self, **external_data):
self.cursor.execute(self, self.construct_query(**external_data))
results = self.cursor.fetchall()
return results
有了上面的class,那么你只需要有一个像下面这样的子class:
class SheepReport(Report):
@property
def query(self):
return "SELECT COUNT(*) FROM sheep WHERE alive = 1;"
不介意无条件self.query % external_data
。它将使用模板字符串或带有 空 字典数据的纯字符串。
我来自 Java 世界,我很难理解与抽象方法相关的 super() 方法。
我有一个带有抽象方法的抽象 class。这个 class' 子 classes 负责查询我的 MySQL 数据库并向我返回格式化报告。在一半的子 class 中,他们使用与 运行 报告完全相同的逻辑。在另一半,每个人都需要自己的逻辑。因此我想使 run_report
成为一个抽象方法。
class Report:
__metaclass__ = ABCMeta
def __init__(self):
self.user = 'root'
self.passwd = ''
self.host = '127.0.0.0.1'
self.port = '80'
self.db = 'animals'
self.conn = mysql.connector.connect(user=self.user, password=self.passd, db=self.db, host=self.host, port=self.port)
self.cursor = self.conn.cursor()
@staticmethod
def construct_query(query, external_data):
finalQuery = query % external_data
return finalQuery
@abstractmethod
def run_report(self, query):
self.cursor.execute(self, query)
results = self.cursor.fetchall()
return data
这是一个 class 的实现示例,它按原样使用抽象方法:
class SheepReport(Report):
query = "SELECT COUNT(*) FROM sheep WHERE alive = 1;"
def run_report(query):
super(Report, self).run_report(query)
这个语法看起来很神秘。我的代码太不完整,目前无法测试 运行,我正在努力将错误消灭在萌芽状态。我对抽象方法的理解正确吗?
相比之下,这里有一个 class 覆盖了 run_report:
class CowReport(Report):
query = "SELECT height, weight FROM cows WHERE name IN (%s);"
def run_report(self):
finalQuery = self.construct_query(query, "'Hilda', 'Gary'");
self.cursor.execute(self, finalQuery)
results = self.cursor.fetchall()
return data
我走在正确的轨道上吗?我看到的所有 super() 和继承的例子都让我头疼,我想我需要有人为我简化它。
首先,我真诚地希望这只是为了学习目的,而不是实际的生产代码。将未经过滤的用户输入传递到查询字符串中等于完全成熟的 SQL injection attack.
除此之外...
抽象 classes 通常用于定义接口,而不是具体的功能。不管你想做什么,只有 query
定义为抽象 属性 的抽象 class 会大大简化你的代码。
class Report:
__metaclass__ = ABCMeta
def __init__(self):
self.user = 'root'
self.passwd = ''
self.host = '127.0.0.0.1'
self.port = '80'
self.db = 'animals'
self.conn = mysql.connector.connect(user=self.user, password=self.passd, db=self.db,
host=self.host, port=self.port)
self.cursor = self.conn.cursor()
@abstractproperty
def query(self):
return NotImplemented
def construct_query(self, **external_data):
finalQuery = self.query % external_data
return finalQuery
def run_report(self, **external_data):
self.cursor.execute(self, self.construct_query(**external_data))
results = self.cursor.fetchall()
return results
有了上面的class,那么你只需要有一个像下面这样的子class:
class SheepReport(Report):
@property
def query(self):
return "SELECT COUNT(*) FROM sheep WHERE alive = 1;"
不介意无条件self.query % external_data
。它将使用模板字符串或带有 空 字典数据的纯字符串。