确定__init __()是否是通过方法调用的结果来调用的



我有一种情况,显然,__init__()被称为方法调用。(不确定为什么;怀疑这可能与需要返回副本有关。(

班级设计的示例:

import copy
import pandas as pd
class TSeries(pd.Series):
    # See:
    # https://pandas.pydata.org/pandas-docs/stable/internals.html
    _metadata = ['some_new_attr']
    def __init__(self, *args, **kwargs):
        # Copy needed because we would otherwise inadvertantly alter
        # mutable arguments such as pd.Series, TSeries, etc.
        args = tuple(copy.deepcopy(arg) for arg in args)
        some_new_attr = kwargs.pop('some_new_attr', None)
        super().__init__(*args, **kwargs)
        print('WE ARE "IN IT."')
        # Put a calculation here that that we *don't* want to call
        # if class instance is instantiated as a result of
        # of self.new_method().
        #
        # _do_some_conditional_calculation(self)
    @property
    def _constructor(self):
        # Used when a manipulation result has the same
        # dimesions as the original.  Fairly sure
        # self.new_method() uses this.
        return TSeries
    def new_method(self):
        return self * 100

调用__init__()的结果:

>>> x = TSeries([1, 2, 3])
WE ARE "IN IT."
>>> x.new_method()
WE ARE "IN IT."      # <-- __init__() called
0    100
1    200
2    300
dtype: int64

我的愿望是在__init__()中对self进行一些内置操作,但是如果由于方法调用而发生呼叫,则 not 。(或更直接,"仅当用户直接实例化TSeries实例时,才执行操作。"(

如何区分这两种情况?


更新 - 这说明了我要做的事情,但似乎很危险。

IS_METHOD_CALL = False

class TSeries(pd.Series):
    # See:
    # https://pandas.pydata.org/pandas-docs/stable/internals.html
    _metadata = ['some_new_attr']
    def __init__(self, *args, **kwargs):
        # Copy needed because we would otherwise inadvertantly alter
        # mutable arguments such as pd.Series, TSeries, etc.
        args = tuple(copy.deepcopy(arg) for arg in args)
        some_new_attr = kwargs.pop('some_new_attr', None)
        super().__init__(*args, **kwargs)
        print('WE ARE "IN IT."')
        # Put a calculation here that that we *don't* want to call
        # if class instance is instantiated as a result of
        # of self.new_method().
        global IS_METHOD_CALL
        if not IS_METHOD_CALL:
            print('Some conditional calculation')
        IS_METHOD_CALL = False
    @property
    def _constructor(self):
        # Used when a manipulation result has the same
        # dimesions as the original.  Fairly sure
        # self.new_method() uses this.
        return TSeries
    def new_method(self):
        # We'd need to do within every single method...
        global IS_METHOD_CALL
        IS_METHOD_CALL = True
        return self * 100

有条件的计算是跳过的:

>>> x = TSeries([1, 2, 3])
WE ARE "IN IT."
Some conditional calculation
>>> x.new_method()
WE ARE "IN IT."
0    100
1    200
2    300
dtype: int64

我认为您必须明确告诉TSeries.__init__才能执行条件计算。没有真正区分对TSeries.__new__的明确和隐式调用(通过type.__call__(TSeries, ...)(。

class TSeries(pd.Series):
    def __init__(self, ..., extra_config=False):
        ...
        if extra_config:
            self._do_some_conditional_calculation()

现在,执行_do_some_conditional_calculation的唯一方法是明确要求:x = TSeries([1,2,3], extra_config=True)

最新更新