Как избежать нескольких блоков Try/Except в Python

У меня есть рабочий код, но я считаю, что наличие множества блоков try/except для обработки исключений очень неэффективно. Есть лучший способ сделать это?

Код, который я сейчас использую, вставлен ниже. Должен ли я выполнять пользовательскую функцию или циклы for? Как его создать?

Код был сокращен из-за требований...

rows = []
rows.append(['Name','Weight', 'Height', 'Season', 'Age', 'Tm', 'Lg', 'Pos', 'G', 'GS', 'MP', 'FG', 'FGA' , 'FGP' , 'P3' , 'PA3' , 'PP3' , 'P2' , 'PA2', 'PP2', 'eFGP' , 'FT', 'FTA' , 'FTP', 'ORB', 'DRB' , 'TRB', 'AST' , 'STL', 'BLK', 'TOV', 'PF' , 'PTS'])

for result in results[1:len(results)]:
    Name = soup.find(name = "h1", attrs = {"itemprop":"name"}).text.strip()
    Weight = soup.find(name = "span", attrs = {"itemprop":"weight"}).text.strip()
    Height = soup.find(name = "span", attrs = {"itemprop":"height"}).text.strip()
    # find all columns per result

    # data = result.find_all('td')
    try:
        season = result.find_all('a')[0]
        season = season.getText()
    except:
        season = 'NA'
    # check that columns have data 
        # if len(data) == 0: 
            # continue
    Season = season
    Age_find = result.find_all('td', attrs = {'data-stat': 'age'})
    Tm_find = result.find_all('td', attrs = {'data-stat': 'team_id'})
    Lg_find = result.find_all('td', attrs = {'data-stat': 'lg_id'})
    Pos_find = result.find_all('td', attrs = {'data-stat': 'pos'})
    G_find = result.find_all('td', attrs = {'data-stat': 'g'})
    GS_find = result.find_all('td', attrs = {'data-stat': 'gs'})
    MP_find = result.find_all('td', attrs = {'data-stat': 'mp_per_g'})
    FG_find = result.find_all('td', attrs = {'data-stat': 'fg_per_g'})
    FGA_find = result.find_all('td', attrs = {'data-stat': 'fga_per_g'})
    FGP_find = result.find_all('td', attrs = {'data-stat': 'fg_pct'})
    P3_find = result.find_all('td', attrs = {'data-stat': 'fg3_per_g'})
    PA3_find = result.find_all('td', attrs = {'data-stat': 'fg3a_per_g'})
    PP3_find = result.find_all('td', attrs = {'data-stat': 'fg3_pct'})
    P2_find = result.find_all('td', attrs = {'data-stat': 'fg2_per_g'})
    PA2_find = result.find_all('td', attrs = {'data-stat': 'fg2a_per_g'})
    PP2_find = result.find_all('td', attrs = {'data-stat': 'fg2_pct'})
    eFGP_find = result.find_all('td', attrs = {'data-stat': 'efg_pct'})
    FT_find = result.find_all('td', attrs = {'data-stat': 'ft_per_g'})
    FTA_find = result.find_all('td', attrs = {'data-stat': 'fta_per_g'})
    FTP_find = result.find_all('td', attrs = {'data-stat': 'ft_pct'})
    ORB_find = result.find_all('td', attrs = {'data-stat': 'orb_per_g'})
    DRB_find = result.find_all('td', attrs = {'data-stat': 'drb_per_g'})
    TRB_find = result.find_all('td', attrs = {'data-stat': 'trb_per_g'})
    AST_find = result.find_all('td', attrs = {'data-stat': 'ast_per_g'})
    STL_find = result.find_all('td', attrs = {'data-stat': 'stl_per_g'})
    BLK_find = result.find_all('td', attrs = {'data-stat': 'blk_per_g'})
    TOV_find = result.find_all('td', attrs = {'data-stat': 'tov_per_g'})
    PF_find = result.find_all('td', attrs = {'data-stat': 'pf_per_g'})
    PTS_find = result.find_all('td', attrs = {'data-stat': 'pts_per_g'})

    try:
        Age = Age_find[0].getText()
    except:
        Age = 'NA'

    try:
        Tm = Tm_find[0].getText()
    except:    
        Tm = 'NA'

    try:
        Lg = Lg_find[0].getText()
    except:    
        Lg = 'NA'

    try:
        Pos = Pos_find[0].getText()
    except:    
        Pos = 'NA'

    try:
        G = G_find[0].getText()
    except:
        G = 'NA'

    try:
        GS = GS_find[0].getText()
    except:    
        GS = 'NA'

    try:
        MP = MP_find[0].getText()
    except:    
        MP = 'NA'

    try:
        FG = FG_find[0].getText()
    except:    
        FG = 'NA'

    try:
        FGA = FGA_find[0].getText()
    except:    
        FGA = 'NA'

    try:
        FGP = FGP_find[0].getText()
    except:    
        FGP = 'NA'

    try:    
        P3 = P3_find[0].getText()
    except:    
        P3 = 'NA'

    try:
        PA3 = PA3_find[0].getText()
    except:    
        PA3 = 'NA'

    try:
        PP3 = PP3_find[0].getText()
    except:    
        PP3 = 'NA'

    try:
        P2 = P2_find[0].getText()
    except:    
        P2 = 'NA'

    try:
        PA2 = PA2_find[0].getText()
    except:    
        PA2 = 'NA'

    try:
        PP2 = PP2_find[0].getText()
    except:    
        PP2 = 'NA'

    try:    
        eFGP = eFGP_find[0].getText()
    except:    
        eFGP = 'NA'

    try:    
        FT = FT_find[0].getText()
    except:    
        FT = 'NA'

    try:
        FTA = FTA_find[0].getText()
    except:    
        FTA = 'NA'

    try:
        FTP = FTP_find[0].getText()
    except:    
        FTP = 'NA'

    try:
        ORB = ORB_find[0].getText()
    except:    
        ORB = 'NA'

    try:    
        DRB = DRB_find[0].getText()
    except:    
        DRB = 'NA'

    try:
        TRB = RRB_find[0].getText()
    except:    
        TRB = 'NA'

    try:
        AST = AST_find[0].getText()
    except:    
        AST = 'NA'


    rows.append([Name, Weight, Height, Season, 
                 Age, Tm, Lg, Pos, G, GS, MP, FG, FGA, 
                 FGP, P3, PA3, PP3, P2, PA2, PP2, eFGP, FT,
                 FTA , FTP, ORB, DRB, TRB, AST, STL, BLK, TOV, PF, PTS])

with open('player_zaid.csv','w', newline='') as f_output:
    csv_output = csv.writer(f_output)
    csv_output.writerows(rows)

Какие исключения вы ожидаете поймать? Никогда не используйте голый except; используйте хотя бы except Exception, чтобы не улавливать такие вещи, как KeyboardInterrupt.

chepner 02.03.2019 15:49

Ваша проблема в том, что у вас есть все эти имена переменных. Вместо этого создайте словарь, и тогда у вас может быть общая функция, которая работает с каждой парой ключ/значение этого словаря.

roganjosh 02.03.2019 15:50

В этом случае также может быть проще просто чек. season = result.find_all('a'); season = season[0].getText() if season else 'NA'. В Python 3.8 вы можете использовать выражение присваивания, чтобы поместить это в одну строку: season = x[0].getText() if (x := result.find_all('a')) else 'NA'.

chepner 02.03.2019 15:57

большое спасибо! Спасибо!

Matthew Loh 03.03.2019 17:08
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
4
556
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

У вас много разделов кода, которые делают одно и то же, что нарушает принцип Не повторяйся (СУХОЙ). Обычный способ избежать этого повторения — написать функцию, скрывающую повторение.

def get_text_or_NA(container):
    try:
        result = container[0].getText()
    except:
        result = 'NA'
    return result

Тогда ваш основной код

Age = get_text_or_NA(Age_find)
Tm = get_text_or_NA(Tm_find)
Lg = get_text_or_NA(Lg_find)

и так далее.

Вы можете использовать аналогичные средства для удаления других повторений в вашем коде — я оставлю их вам. И, как говорится в комментарии @roganjosh, вам действительно не следует использовать except: без исключения. Ваш способ просто скрывает всю проблему. Будьте более конкретными и скрывайте только те исключения, которые вы ожидаете, чтобы неожиданные могли быть обнаружены на более высоком уровне.

Вы могли бы развить этот много и просто не иметь всех этих имен переменных. Они должны пользоваться словарем.

roganjosh 02.03.2019 15:56

Согласен с @roganjosh.

Mehrdad Pedramfar 02.03.2019 15:56

@roganjosh: я согласен с тобой. Я сосредоточил свой ответ на фактическом вопросе, заданном ОП. Обратите внимание на первую строку моего последнего абзаца, которую я печатал, когда вы давали свой комментарий, — то, что вы заметили, — это то, что я имел в виду. Я попытался сбалансировать ответ на фактический вопрос и дать дополнительные советы.

Rory Daulton 02.03.2019 15:58

Я не упомянул одеяло Except, это было чепнер :), но, честно говоря, это все еще приличное улучшение исходного кода.

roganjosh 02.03.2019 15:59

Другие вопросы по теме