python - 在方法开头组合检查

标签 python python-3.x

我有几种类似于以下的方法:

@property
def tpr_num_days(self):
    """
    The duration, in days, of the TPR interval.
    """
    if not self.prices:
        raise RuntimeError("Must initialize self.prices first.")

    # do something

@property
def revenue_during_tpr_is_greatest(self):
    """
    Tells us if the Revenue that was generated during the TPR was both greater
    than the revenue that was generated in the same-duration interval before the TPR and after the TPR.
    """
    if not self.prices:
        raise RuntimeError("Must initialize self.prices first.")

    # do something

def build_pricing_data(self):
    """
    This will build a list of pricing objects.

    Note that we are currently excluding "returns" because the price of the returned
    item may be different than the current price of the product, which could open up
    a can of worms trying to track down when that item was purchased.
    """
    cursor.execute('''SELECT
                            date,
                            max(if(offer_code='sdbuy', price, null)) sd_buy_price,
                            max(if(offer_code='hdbuy', price, null)) hd_buy_price,
                            max(if(offer_code='sdrent', price, null)) sd_rent_price,
                            max(if(offer_code='hdrent', price, null)) hd_rent_price,
                            sum(revenue) revenue
                      FROM price_date WHERE apple_id=%s and territory=%s and revenue > 0
                      GROUP BY date
                      ORDER BY date
                      ''', (self.apple_id, self.territory))

    # let's make sure it's re-initialized in case it's called multiple times.
    self.prices = []     
    for row in cursor:
        pricing_obj = {"date": item[0], "SDBUY": item[1], "HDBUY": item[2], "SDRENT": item[3], "HDRENT": item[4], "REVENUE": item[5]}
        self.prices.append(pricing_obj)

除了在许多方法的开头使用这个 if 语句,还有什么更好的方法来封装它?

最佳答案

您可以使用函数装饰器:

import functools

def requires_price(func):
    @functools.wraps(func)
    def wrapper(obj, *args, **kwargs):
        if not obj.prices:
            raise RuntimeError("Must initialize self.prices first.")

        return func(obj, *args, **kwargs)

    return wrapper

使用方式如下:

@property
@requires_price
def tpr_num_days(self):
    ... # do something

或者您可以更进一步,将装饰器实现为 descriptor ,这可以让您省略 @property:

class price_property:
    def __init__(self, func):
        self.func = func

    def __get__(self, instance, owner):
        if instance is None:
            return self

        if not instance.prices:
            raise RuntimeError("Must initialize self.prices first.")

        return self.func(instance)

使用方式如下:

@price_property
def tpr_num_days(self):
    ... # do something

关于python - 在方法开头组合检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58329083/

相关文章:

python - Markdown 语法突出显示调用 Python 脚本的 Bash 命令

python - 启动 PyCharm 时连接到远程解释器

python-3.x - 旁加载静态数据

python - 在 Python3 中使用 `random.shuffle` 作为关键字参数时 `random.random` 的运行时间更短

python - 是否可以动态定义函数参数的名称?

python - 如何在另一个 ndarray 中找到一个 ndarray 的索引

python - paramiko python 模块卡在 stdout.read()

python - 使用 key_name 和属性查询之间的性能差异

python - Vim:在 Python 源文件中获得自动缩进,但没有智能缩进

python - python归并排序中递归的使用