파이썬3 노트

[**kwargs] [assert]

Jonchann 2018. 12. 17. 17:52

함수를 만들 때 인수로 *args를 넣으면 (정확하게 말하자면 * 를 붙인 인수인데 보통은 저렇게 적으니까) 0개 이상의 인수가 들어올 수도 있고 아닐 수도 있으며 입력될 때에는 몇 개나 입력이 될지 정해놓지 않았다는 이야기가 된다.



1. **kwargs


하지만 인수 중에는 키워드 인수라는 것이 있다.

이건 값을 정해놓은 인수를 말하며 함수를 만들 때 키워드 인수는 가장 마지막으로 가야 한다.


예로, 아까 올린 pathlib글에 적은 함수를 약간 수정해서 가져오겠다.

import torch
from torchtext.data import Dataset, Example, Field, LabelField, RawField
import csv


class DataLoadwithPath(Dataset):
    urls = [
        'url1'
        'url2'
    ]


    def __init__(self, fst_path, scd_path, fields, filter=None):
        datum = []
        for (fst_data, scd_data) in zip(fst_iter(fst_data_path), scd_iter(scd_data_path)):
            assert fst_data == scd_data
            datum.append(Example.fromlist([fst_data, scd_path], fields))
        super(DataLoadwithPath, self).__init__(datum, fields, filter)


    @classmethod
    def load(cls, path=None, root=dir_folder / 'dataset folder name', **kwargs):
        if path is None:
            new_path = cls.download(root)
        fst_train = Path(new_path) / 'file name'
        fst_val = Path(new_path) / 'file name'
        fst_test = Path(new_path) / 'file name'

        scd_train = Path(new_path) / 'file name'
        scd_val = Path(new_path) / 'file name'
        scd_test = Path(new_path) / 'file name'

        return (fst_train, scd_train, **kwargs), \
                   (fst_val, scd_val, **kwargs), \
                   (fst_test, scd_test, **kwargs), \


    @classmethod
    def process(cls, arg, filter=None, ... ):
         ...
        train, val, test = cls.load(fields=[ ... ], filter=filter)
        return 

__init__()의 인수는 self, fst_path, scd_path, fields, filter가 들어있는데 load()에는 fields, filter 대신에 **kwargs가 들어가 있다. 그리고 함수 내에서 fields, filter라는 인수는 사용되지도 않았다.

하지만 마지막 process()에서는 cls.load()로 위 함수를 불러 그 안에 fields와 filter의 내용을 채워주었다.

이처럼 일단 사용하지 않는 키워드 인수를 다 적지 않고 다음 함수에 대충 넘길 때 **kwargs라 적는다 한다.


이런 방법을 알려준 선배는 이게 나쁜 습관이라는 설명을 덧붙였는데 왜냐하면, 여럿이서 함수를 적을 땐 저런 식으로 넘기면 뭐가 인수로 들어와있는지 모르기 때문에 제대로 코딩을 할 수 없다고 했다. 하지만 혼자 적을 땐 **kwargs라고 적는다 한들 모르진 않을 것이므로 저런식으로 간단히 처리하기도 한다고.



2. assert


그대로 위에 있는 코드를 두고 적자면.

__init__()에 assert fst_data == scd_data 라 적혀있다.


일단 assert가 뭐냐하면: [assert 조건] 이라 적었을 때 조건을 충족하지 않는다면 에러를 내라 할 때 사용하는 것이다.

if/else문이나 try/except문처럼 조건에 해당하지 않는 경우에 대응하지 않는 이유는 '에러가 절대 나지 않는다는 확신'을 갖고 있지만 일단 저것이 맞는지 검증하기 위한 용도로 사용하기 때문이라고 한다.