编写接受多种类型的库函数的 Pythonic 方式?

标签 python

如果作为一个简化示例,我正在编写一个库来帮助人们对人口建模,我可能会有一个类,例如:

class Population:
    def __init__(self, t0, initial, growth):
        self.t0 = t0,
        self.initial = initial
        self.growth = growth

其中 t0 是日期时间类型。现在我想提供一种方法来确定给定时间的人口,无论是日期时间还是包含自 t0 以来的秒数的 float 。此外,调用者提供此类时间的数组是合理的(如果是这样,我认为假设它们都属于同一类型是合理的)。至少有两种方法可以实现此目的:

  1. 每种类型的方法

    def at_raw(self, t):
        if not isinstance(t, collections.Iterable):
            t = numpy.array([t])
        return self.initial*numpy.exp(self.growth*t)
    def at_datetime(self, t):
        if not isinstance(t, collections.Iterable):
            t = [t]
        dt = numpy.array([(t1-self.t0).total_seconds() for t1 in t])
        return self.at_raw(dt)
    
  2. 通用方法

    def at(self, t):
        if isinstance(t, datetime):
            t = (t-self.t0).total_seconds()
        if isinstance(t, collections.Iterable):
            if isinstance(t[0], datetime):
                t = [(t1-self.t0).total_seconds() for t1 in t]
        else:
            t = np.array([t])
        return self.initial*numpy.exp(self.growth*t)
    

两者都可以,但我不确定哪个更 pythonic。我看到一些建议,类型检查表明设计不当,这会建议方法 1,但由于这是一个供其他人使用的库,方法 2 可能更有用。

请注意,有必要支持以 float 形式给出的时间,即使只有库本身使用此功能,例如,我可能会实现一种方法,该方法在更复杂的模型中找到固定点,其中浮点表示显然更可取.在此先感谢您的任何建议或建议。

最佳答案

我相信您可以在这里简单地坚持 Python 的 Duck Typing 哲学

def at(self, t):
    def get_arr(t):
        try: # Iterate over me
            return [get_arr(t1)[0] for t1 in t]
        except TypeError:
            #Opps am not Iterable
            pass
        try: # you can subtract datetime object
            return [(t-self.t0).total_seconds()]
        except TypeError:
            #Opps am not a datetime object
            pass
        # I am just a float
        return [t]
    self.initial*numpy.exp(self.growth*np.array(get_arr(t)))

这很重要,你如何订购这些箱子

  1. 具体案例应该先于一般案例。

    def foo(num):
        """Convert a string implementation to
           Python Object"""
        try: #First check if its an Integer
            return int(num)
        except ValueError:
            #Well not an Integer
            pass
        try: #Check if its a float
            return float(num)
        except ValueError:
            pass
        #Invalid Number
        raise TypeError("Invalid Number Specified")
    
  2. Default Case 应该是终止案例

  3. 如果连续的案例相互排斥,则按可能性排序。
  4. 通过抛出 Exception 来为意外做好准备。毕竟错误不应该悄无声息地过去。

关于编写接受多种类型的库函数的 Pythonic 方式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19365600/

相关文章:

python - Knn 预测在 y_test 上达到 100%

python - 如何从处理程序中退出异步调度程序?

python - 在 Django 1.9 中保存时将用户添加到组

python - 如何在 Django REST Framework 中测试 FileField

python - 如何使用 python(和 Gtk3)制作全局键盘快捷键?

python - 如何部署 GCP App Engine Worker?

python - 如何在 Python 中表达类型

python - 如何使用 tf.where() 根据条件替换特定值

python - 使用 Python 库生成有向图 任何 python 库

python - AWS : Running scheduled Python code to update a static S3 page