numpy 有没有一种方法可以使用classmethod来构造一个具有示例属性集的示例,而无需调用python中的__init__?

huus2vyu  于 2023-08-05  发布在  Python
关注(0)|答案(1)|浏览(78)

这是我的代码,希望是自我解释的。

import os
import numpy as np

class MyApp:
    
    def __init__(self, x, y, project_name):
        '''default constructor'''
        
        # Build Project if Non-Existent
        if not os.path.exists(project_name):
            os.makedirs(project_name)
        
        # Attribute Arrays
        self.arr1 = np.arange(x) # Dummy task based on x
        self.arr2 = np.arange(y) # Dummy task based on y
        
        # Dump Arrays
        np.save(f'{project_name}/arr1.npy', self.arr1)
        np.save(f'{project_name}/arr2.npy', self.arr2)
    
    @classmethod
    def from_project(cls, project_name):
        '''load objects from project'''
        
        # Check if project exists
        if not os.path.exists(project_name):
            raise FileNotFoundError(f'{project_name} missing')
        
        # Now load arr1 and arr2
        arr1 = np.load(f'{project_name}/arr1.npy')
        arr2 = np.load(f'{project_name}/arr2.npy')
        
        # And return an instance with self.arr1 and self.arr2 set
        pass # ????
    
    def task_A(self):
        '''do some task based on arr1'''
        return self.arr1.mean()
    
    def task_B(self):
        '''do some task based on both arr1 and arr2'''
        return np.convolve(self.arr1, self.arr2)

# Init Object
app = MyApp(x=5, y=10, project_name='testing_tmp')
print(type(app)) # <class '__main__.MyApp'>

# Initally Tasks OK
print(app.task_A()) # 2.0
print(app.task_B()) # [ 0  0  1  4 10 20 30 40 50 60 70 70 59 36]

# No Tasks after Object Deletion
del app
try:
    print(app.task_A()) # No execution
    print(app.task_B()) # No execution
except:
    pass

# Now want to instantiate object from project
app = MyApp.from_project(project_name='testing_tmp')
print(type(app)) # <class 'NoneType'>

字符串
输出如下:

<class '__main__.MyApp'>
2.0
[ 0  0  1  4 10 20 30 40 50 60 70 70 59 36]
<class 'NoneType'>


有没有一种方法可以编写一个classmethod,它可以从文件中读取保存的对象属性,并根据需要返回一个设置了正确属性的示例?
我知道我也可以将xy的值保存到磁盘上,并使用类似return cls(x=disk_x, y=disk_y, project_name=project_name)的东西,但我的真实的任务不允许这样做,因为从xy创建的对象计算起来相当昂贵,因此我将它们创建并保存到磁盘上以供以后使用。
为清晰起见编辑:我的目标是使用from_project方法返回一个正确设置了self.arr1self.arr2属性的类示例,而不使用__init__()方法,因为__init__()方法需要设置xy。请参阅from_project方法,了解我在哪里变得毫无头绪的细节。我知道如何序列化和反序列化对象和类属性,这不是我关心的问题。
我尝试使用from_projectclassmethodcls属性来设置cls.arr1cls.arr2,但它不起作用。

5fjcxozz

5fjcxozz1#

是的,我找到答案了。技巧是使用__new__方法进行示例化,然后绕过__init__来设置属性并返回示例。下面是对from_project所需的方法更改。

@classmethod
def from_project(cls, project_name):
    '''load objects from project'''

    # Check if project exists
    if not os.path.exists(project_name):
        raise FileNotFoundError(f'{project_name} missing')

    # Now load arr1 and arr2
    arr1 = np.load(f'{project_name}/arr1.npy')
    arr2 = np.load(f'{project_name}/arr2.npy')

    # And return an instance with self.arr1 and self.arr2 set

    # First we use the __new__ method for instantiation
    instance = cls.__new__(cls)

    # Then we set attributes
    instance.arr1 = arr1
    instance.arr2 = arr2

    # Return the instance
    return instance

字符串

相关问题