亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何從父實例調用子類中的方法?

如何從父實例調用子類中的方法?

神不在的星期二 2022-08-25 15:33:33
如何在 中創建的實例并調用方法?如下圖所示:StatsGameStatsclass 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()]
查看完整描述

3 回答

?
慕萊塢森

TA貢獻1810條經驗 獲得超4個贊

“簡單勝于復雜”和“實用性勝過純度”-- PEP 20

#What I want to do

d.Stats()

d.team_standings()

d.player_stats()

d.fixture_stats()

你的例子都是在一個賽季的背景下。因此,我只需將其作為一個包含您要使用的所有方法的類即可。這也清楚地表明,這些方法僅限于該單一季節。SeasonStats


class SeasonStats:

    ...

    def __init__(self, league='EN_PR', season='2019/2020'):

        ...


        ### Included from '__init__'s of previous subclasses ###

        self.fixture_ids = [fix['id'] for fix in self.load_season_fixture().values()]

        self.team_ids = [team['id'] for team in self.load_season_teams().values()]

        self.player_ids = self.load_season_players()


    def load_season_fixture(self):

        ...

    def load_season_players(self):

        ...

    def load_season_teams(self):

        ...

    def fixture_stats_singel(self, fixture):

        ...

    def fixture_stats(self):

        ...

    def player_stats_singel(self, player):

        ...

    def player_stats(self):

        ...

    def team_standings_singel(self, team_id):

        ...

    def team_standings(self):

        ...

請注意,我已經巧妙地更改了從以前的子類中包含的變量名稱__init__


然后確實只是將其用作:


season_19_20 = SeasonStats(season='2019/2020')

season_19_20.team_standings()

season_19_20.player_stats()

season_19_20.fixture_stats()

一些變量命名建議

d, ,ef

我建議不要使用 、 、 等...內存很便宜,屏幕足夠大:不要害怕使用有意義的名稱,例如.abcseason


列表是復數

在談論ID列表時,您自然已經使用了復數“ID”。通過這樣命名變量,您可以輕松區分事物列表和單個事物。這也使得在例如 -loop 中使用非常自然:for


team_ids = [team['id'] for team in ...]

for team_id in team_ids:

    do_something_with(team_id)


查看完整回答
反對 回復 2022-08-25
?
當年話下

TA貢獻1890條經驗 獲得超9個贊

從評論中獲得更多上下文:

所以。。。你不想有一個子對象,你只是想在原來的類中有更多的方法嗎?但是,如果不將這些方法放在原始類中呢?

@h4ze聽起來沒錯!我想要碎片化

如果顯式指定類名,則可以將任何內容作為 傳遞。self

d = Stats()
GameStats.fixture_stats(d)

它被稱為鴨子打字 - 我們不關心物體的實際類型,我們關心它的作用:“如果它像鴨子一樣游泳,像鴨子一樣嘎嘎叫,它就是鴨子”。

這允許您將任何對象傳遞到任何地方...但這也意味著物體需要像最初期望的物體一樣“游泳”和“庸醫”,對吧?

我們知道所有對象都是對象(因為繼承),但不是相反。- 這意味著你的方法只能使用有的東西。GameStatsStatsGameStatsStats


但是,僅僅因為你可以做某事并不意味著你應該這樣做。你不能利用你的孩子類的潛力 - 你基本上只是使用類作為不同類的方法的存儲!


更好的主意是以另一種方式進行 - 使用多重繼承。每個父類都將具有執行其操作所需的內容(當然,您將在子 init 中設置所有這些部分)和這些操作 - 從而最大限度地減少在子類中覆蓋方法的需求。

把它想象成其他語言的接口,但是已經實現的方法(通常你必須實現接口 - 導致類中有更多的東西)。


或者只是做普通的函數,記錄(在文檔字符串中)他們應該接受給定的對象,并使用它。您可以將這些函數存儲在不同的模塊中,從而為它們提供不同的命名空間 - 提供所需的“碎片”。


查看完整回答
反對 回復 2022-08-25
?
臨摹微笑

TA貢獻1982條經驗 獲得超2個贊

這是一個糟糕的設計。所以我的答案是你不應該那樣做。


這很危險,因為來自子類的方法需要一個可能具有其他屬性的子類對象。在基類對象上調用這些方法可能會中斷。在您的示例中,只有真正的對象才會初始化GameStatsfixture_id


好吧,如果你仔細地寫,它會起作用,但它需要用紅色閃爍的字體注釋,以防止未來的維護者不要破壞它,因為你愿意濫用類層次結構。


如果要構建基類對象,并且以后使用子類中的方法,則可以使用可接受的設計:


確保所有子類都可以從基類對象初始化,然后執行以下操作:


d = Stats()

# additional Stats operation on d...

(GameStats(d)).fixture_stats()

使用將從其他混煉中加載方法(手動等效于上述設計)__getattr__


class Base:

    def set_mixin(self, mixin):

        self.mixin = mixin

    def __getattr__(self, attr):

        return functools.partial(getattr(self.mixin, attr), self)


class M1:

    """Mixin for class Base: only contains methods that apply on Base objects"""

    def __init__(self, *args, **kwargs):

        raise TypeError("Cannot create M1 objects")

    def foo(self, x):

        print(x, 'on', self)


b = Base()

b.set_mixin(M1)

b.foo('x')

會打印


x on <__main__.Base object at 0x...>

但恕我直言,這是一個有問題的設計,應該只用于特殊用例。


查看完整回答
反對 回復 2022-08-25
  • 3 回答
  • 0 關注
  • 139 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號