python - 如何从父实例调用子类中的方法?
问题描述
如何Stats
在 in 上创建实例并调用方法GameStats
?如下所示:
class Stats():
"""Object to instansiate a league and season pair
Args:
league(str): league_id
season(str): season_id
"""
fb = Football()
dir = Directory()
def __init__(self, league='EN_PR', season='2019/2020'):
self.pool = multiprocessing.cpu_count()
self.league = league
self.season = season
def load_season_fixture(self):
"""Loads the fixtures for a league-season,
calls api_scraper.py methods
"""
self.fb.load_leagues()
self.fb.leagues[self.league].load_seasons()
return self.fb.leagues[self.league].seasons[self.season].load_played_fixtures()
def load_season_players(self):
"""Loads the players for a league-season,
calls api_scraper.py methods
"""
player_id = []
self.fb.load_leagues()
self.fb.leagues[self.league].load_seasons()
teams = self.fb.leagues[self.league].seasons[self.season].load_teams()
for team in tqdm(teams.values()):
players = self.fb.leagues[self.league].seasons['2019/2020'].teams[team['shortName']].load_players()
for player in players.keys():
player_id.append(player)
return player_id
def load_season_teams(self):
"""Loads the teams for a league-season,
calls api_scraper.py methods
"""
player_id = []
self.fb.load_leagues()
self.fb.leagues[self.league].load_seasons()
return self.fb.leagues[self.league].seasons[self.season].load_teams()
class GameStats(Stats):
def __init__(self, *args, **kwargs):
super().__init__()
self.fixture_id = [fix['id'] for fix in self.load_season_fixture().values()]
def fixture_stats_singel(self, fixture):
"""Gets stats for a fixture"""
ds = load_match_data(f'https://footballapi.pulselive.com/football/stats/match/{fixture}')
return ds
def fixture_stats(self):
"""Gets stats for all fixtures in a league-season using multithreading
saves output in a json file.
"""
stats = {}
with Pool(self.pool) as p:
fixture_stats = list(tqdm(p.imap(self.fixture_stats_singel, self.fixture_id, chunksize=1), total=len(self.fixture_id)))
i = 0
for fixture in fixture_stats:
game_id = fixture['entity']['id'] #Get's the gameIDs for each game
index = game_id #Set's gameIDs as index for dictionairy
stats[index] = {'info': fixture['entity']}
print(f'Saved as {filename}.json in {path}')
class PlayerStats(Stats):
def __init__(self, *args, **kwargs):
super().__init__()
self.player_id = self.load_season_players()
def player_stats_singel(self, player):
#NEED TO HAVE SEASON ID
season_id = self.fb.leagues[self.league].seasons[self.season]['id']
ds = load_match_data(
f'https://footballapi.pulselive.com/football/stats/player/{player}?compSeasons={season_id}')
return ds
def player_stats(self):
stats = {}
with Pool(self.pool) as p:
player_stats = list(tqdm(p.imap(self.player_stats_singel, self.player_id, chunksize=1), total=len(self.player_id)))
all_players = player_stats
i = 0
for player in all_players:
game_id = int(player['entity']['id']) #Get's the gameIDs for each game
index = game_id #Set's gameIDs as index for dictionairy
stats[index] = {'info': player['entity']}
print(f'Saved as {filename}.json in {path}')
class TeamStandings(Stats):
def __init__(self, *args, **kwargs):
super().__init__()
self.team_id = [fix['id'] for fix in self.load_season_teams().values()]
def team_standings_singel(self, team_id):
#NEED TO HAVE SEASON ID
season_id = self.fb.leagues[self.league].seasons[self.season]['id']
ds = load_match_data(
f'https://footballapi.pulselive.com/football/compseasons/{season_id}/standings/team/{team_id}')
return ds
def team_standings(self):
stats = {}
with Pool(self.pool) as p:
team_standings = list(tqdm(p.imap(self.team_standings_singel, self.team_id, chunksize=1), total=len(self.team_id)))
i = 0
team_standing = team_standings
for team in team_standing:
team_id = int(team['team']['club']['id']) #Get's the gameIDs for each game
index = team_id #Set's gameIDs as index for dictionairy
if 'compSeason' in team:
stats[index] = {'season': team['compSeason']}
print(f'Saved as {filename}.json in {path}')
#What I'm doing right now
d = TeamStandings()
d.team_standings()
e = PlayerStats()
e.player_stats()
f = GameStats()
f.fixture_stats()
#What I want to do
d.Stats()
d.team_standings()
d.player_stats()
d.fixture_stats()
解决方案
随着评论的更多背景:
所以......你不想有一个子对象,你只想在原始类中有更多的方法?但是没有将这些方法放在原始类中?
@h4ze 听起来不错!我想要碎片化
如果您明确指定类名,则可以将任何内容作为self
.
d = Stats()
GameStats.fixture_stats(d)
这被称为鸭子类型——我们不关心对象的实际类型,我们关心它的作用:“如果它像鸭子一样游泳并且像鸭子一样嘎嘎叫,那它就是一只鸭子”。
这允许您将任何对象传递到任何地方......但这也意味着该对象需要像最初预期的对象一样“游泳”和“嘎嘎”,对吧?
我们知道所有GameStats
对象都是Stats
对象(因为继承),但反之则不然。- 这意味着您的方法GameStats
只能使用Stats
具有的东西。
但仅仅因为你可以做某事并不意味着你应该做。你不能使用你的子类的潜力——你基本上只是将类用作不同类的方法的存储!
更好的主意是反过来做——使用多重继承。每个父类都将具有执行其操作所需的内容(当然,您将在子初始化中设置所有这些部分)和这些操作 - 从而最大限度地减少覆盖子方法的需要。
把它想象成其他语言的接口,但是已经实现了方法(通常你必须实现接口——在类中导致更多的东西)。
或者只是做普通的函数,记录(在文档字符串中)他们应该接受给定的对象,然后使用它。您可以将这些函数存储在不同的模块中,从而为它们提供不同的名称空间 - 提供您想要的“碎片”。
推荐阅读
- apache-kafka - 更好的方法来监听数百个 Kafka 主题并将数据存储到数据库中
- javascript - Plotly JavaScript - 甜甜圈图 - Hoverinfo,尝试使用数组添加自定义定义 - 我的代码的小问题
- sql-server - 如何在 T-SQL 中重置/重新启动 SQL Server 中的主键?
- apache-kafka - 如何在融合控制中心配置数据生成连接器
- laravel - 如何获取期权价值相关产品(Laravel)
- android - DaggerApp_HiltComponents_ApplicationC.java 编译时错误 - 找不到符号
- javascript - 如何为 mat-select 设置默认值?
- flutter - 如何让 ModalBottomSheet 的子 Widget 像下图一样突出在顶部:
- r - 如何使用部分匹配的字符串进行子集化?
- python - BeatifulSoup 无法从滚动页面加载所有图像