Как создать экземпляр класса из внутреннего метода, используя @classmethod? [например. pd.MultiIndex.from_tuples ()] - PullRequest
0 голосов
/ 08 марта 2019

Я чувствую, что, возможно, я вырезал фразу для этого, но я пытаюсь создать экземпляр класса из внутреннего метода. Например, в pandas есть объект MultiIndex, который может быть создан как (A) MultiIndex(*args), так и (B) MultiIndex.from_tuples(*args) [или другими .from_ методами]. Я пытаюсь сделать последнее.

class ExampleClass(object):
    def __init__(self, name=None, data_1=None, data_2=None):
        self.name = name
        self.data_1 = data_1
        self.data_2 = data_2
    def from_custom(self, t, name=None):
        self.data_1 = np.sin(t)
        self.data_2 = np.cos(t)
        self.name = name
        return self

t = np.linspace(0, 2*np.pi)
r_sin = np.sin(t)
r_cos = np.cos(t)
obj_A = ExampleClass(name="test", data_1=r_sin, data_2=r_cos)
obj_B = ExampleClass.from_custom(t, name="test")
# ---------------------------------------------------------------------------
# TypeError                                 Traceback (most recent call last)
# <ipython-input-12-26ccb0eee5a1> in <module>
#      14 obj_A = ExampleClass(name="test", data_1=r_sin, data_2=r_cos)
#      15 
# ---> 16 obj_B = ExampleClass.from_custom(t)

# TypeError: from_custom() missing 1 required positional argument: 't'

Я посмотрел исходный код для pd.MultiIndex через ??pd.MultiIndex и заметил, что был декоратор @classmethod. Я добавил декоратор и теперь он работает.

class ExampleClass(object):
    def __init__(self, name=None, data_1=None, data_2=None):
        self.name = name
        self.data_1 = data_1
        self.data_2 = data_2
    @classmethod
    def from_custom(self, t, name=None):
        self.data_1 = np.sin(t)
        self.data_2 = np.cos(t)
        self.name = name
        return self

t = np.linspace(0, 2*np.pi)
r_sin = np.sin(t)
r_cos = np.cos(t)
obj_A = ExampleClass(name="test", data_1=r_sin, data_2=r_cos)
obj_B = ExampleClass.from_custom(t, name="test")
print(obj_B.name, obj_B.data_1[:5], obj_B.data_2[:5], sep="\n")
# test
# [0.         0.12787716 0.25365458 0.375267   0.49071755]
# [1.         0.99179001 0.96729486 0.92691676 0.8713187 ]

Я правильно это делаю? Я никогда раньше не использовал @classmethod или @staticmethod, и я не совсем уверен, что они делают после прочтения документации.

Является ли это / правильный способ создания объекта из внутреннего метода?

РЕДАКТИРОВАТЬ: В ответ на комментарий ниже:

class ExampleClass(object):

    def __init__(self, **kwargs):
        for k,v in kwargs.items():
            setattr(self, k,v)
    @classmethod
    def from_custom(cls, t, name=None):
        data_1 = np.sin(t) * np.random.random()
        data_2 = np.cos(t) * np.random.random()
        name = name
        return cls(name=name, data_1=data_1, data_2=data_2)

t = np.linspace(0, 2*np.pi)
r_sin = np.sin(t)
r_cos = np.cos(t)

np.random.seed(0)
obj_A = ExampleClass(name="test_A", data_1=r_sin, data_2=r_cos)
obj_B = ExampleClass.from_custom(t, name="test_B")
obj_C = ExampleClass.from_custom(t, name="test_C")

for obj in [obj_A, obj_B, obj_C]:
    print(obj.name, obj.data_1[:5], obj.data_2[:5], "\n", sep="\n")
# test_A
# [0.         0.12787716 0.25365458 0.375267   0.49071755]
# [1.         0.99179001 0.96729486 0.92691676 0.8713187 ]


# test_B
# [0.         0.07018071 0.13920906 0.2059516  0.26931242]
# [0.71518937 0.70931767 0.691799   0.66292101 0.62315787]


# test_C
# [0.         0.07707967 0.15289369 0.22619721 0.29578657]
# [0.54488318 0.5404097  0.5270627  0.50506135 0.47476691]
...