What is a clean, pythonic way to have multiple constructors in Python?

后端 未结 13 2099
醉梦人生
醉梦人生 2020-11-22 07:12

I can\'t find a definitive answer for this. As far as I know, you can\'t have multiple __init__ functions in a Python class. So how do I solve this problem?

13条回答
  •  盖世英雄少女心
    2020-11-22 07:27

    This is how I solved it for a YearQuarter class I had to create. I created an __init__ which is very tolerant to a wide variety of input.

    You use it like this:

    >>> from datetime import date
    >>> temp1 = YearQuarter(year=2017, month=12)
    >>> print temp1
    2017-Q4
    >>> temp2 = YearQuarter(temp1)
    >>> print temp2
    2017-Q4
    >>> temp3 = YearQuarter((2017, 6))
    >>> print temp3
    2017-Q2 
    >>> temp4 = YearQuarter(date(2017, 1, 18))
    >>> print temp4
    2017-Q1
    >>> temp5 = YearQuarter(year=2017, quarter = 3)
    >>> print temp5
    2017-Q3
    

    And this is how the __init__ and the rest of the class looks like:

    import datetime
    
    
    class YearQuarter:
    
        def __init__(self, *args, **kwargs):
            if len(args) == 1:
                [x]     = args
    
                if isinstance(x, datetime.date):
                    self._year      = int(x.year)
                    self._quarter   = (int(x.month) + 2) / 3
                elif isinstance(x, tuple):
                    year, month     = x
    
                    self._year      = int(year)
    
                    month           = int(month)
    
                    if 1 <= month <= 12:
                        self._quarter   = (month + 2) / 3
                    else:
                        raise ValueError
    
                elif isinstance(x, YearQuarter):
                    self._year      = x._year
                    self._quarter   = x._quarter
    
            elif len(args) == 2:
                year, month     = args
    
                self._year      = int(year)
    
                month           = int(month)
    
                if 1 <= month <= 12:
                    self._quarter   = (month + 2) / 3
                else:
                    raise ValueError
    
            elif kwargs:
    
                self._year      = int(kwargs["year"])
    
                if "quarter" in kwargs:
                    quarter     = int(kwargs["quarter"])
    
                    if 1 <= quarter <= 4:
                        self._quarter     = quarter
                    else:
                        raise ValueError
                elif "month" in kwargs:
                    month   = int(kwargs["month"])
    
                    if 1 <= month <= 12:
                        self._quarter     = (month + 2) / 3
                    else:
                        raise ValueError
    
        def __str__(self):
            return '{0}-Q{1}'.format(self._year, self._quarter)
    

提交回复
热议问题