使用类组织创建或扩展文本文件的函数?

2024-09-29 17:18:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我对课程是全新的,我真的不知道什么时候使用它们。我想写一个程序来模拟EPR/NMR谱,它需要关于模拟系统的信息。相关的事情是这样的:我有一个名为rel_inty(I_n,N)的函数,它从两个值计算相关信息。问题是,当这些值中的任何一个变大(I_n,N >= 10)时,速度会变得非常慢。这就是为什么我选择预先计算(rel_inty(I_n,N))的最相关组合,并将它们保存在字典中。我将该字典写入一个文件,并可以使用eval()导入它,因为每次执行时动态计算rel_inty(I_n,N)会太慢

现在我有了以下想法:如果我创建一个class manage_Dict():,如果旧文件被删除,它的方法可以用def basic():重新创建一个基本字典,或者用def expand():方法扩展现有的字典,如果基本字典不包含用户指定的(I_n,N)的组合,该怎么办

这将是该课程的大纲:

class manage_Dict(args):

    def rel_inty(I_n,N):
        '''calculates relative intensities for a combination (I_n,N)'''

    def basic():
        '''creates a dict for preset combinations of I_n,N'''

        with open('SpinSys.txt','w') as outf:

            Dict = {}
            I_n_List = [somevalues]
            N_List = [somevalues]

            for I_n in I_n_List:
                Dict[I_n] = {}
                for N in N_List:
                    Dict[I_n][N] = rel_inty(I_n,N)

            outf.write(str(Dict))

    def expand(*args):
        '''expands the existing dict for all tuples (I_n,N) in *args'''

        with open('SpinSys.txt','r') as outf:

            Dict = eval(outf.read())

            for tup in args:
                I_n = tup[0]
                N = tup[1]

                Dict[I_n][N] = rel_inty(I_n,N)

         os.remove('SpinSys.txt')

         with open('SpinSys.txt','w') as outf:

             outf.write(str(Dict))

用法:

'''Recreate SpinSys.txt if lost'''
manage_Dict.basic()

'''Expand SpinSys.txt in case of missing (I_n,N)'''
manage_Dict.expand((10,5),(11,3),(2,30))

这是一个明智的解决方案吗?我很好奇,因为我通常看到带有self__init__的类创建一个对象实例,而不仅仅是管理函数调用


Tags: intxtfor字典managebasicdefargs
1条回答
网友
1楼 · 发布于 2024-09-29 17:18:08

如果我们要使用一个对象,让我们确保它为我们做了一些有用的工作,并且界面比只使用函数更好。我将建议一些重大调整,使生活更轻松:

  • 我们可以将dict本身分为子类,然后我们的对象就是一个dict,以及所有定制的奇特东西
  • 使用JSON代替文本文件,这样我们就可以快速、自然、安全地序列化和反序列化
import json


class SpectraDict(dict):
    PRE_CALC_I_N = ["...somevalues..."]
    PRE_CACL_N = ["...somevalues..."]

    def rel_inty(self, i_n, n):
        # Calculate and store results from the main function
        if i_n not in self:
            self[i_n] = {}

        if n not in self[i_n]:
            self[i_n][n] = self._calculate_rel_inty(i_n, n)

        return self[i_n][n]

    def _calculate_rel_inty(self, i_n, n):
        # Some exciting calculation here instead...
        return 0

    def pre_calculate(self):
        s_dict = SpectraDict()

        for i_n in self.PRE_CALC_I_N:
            for n in self.PRE_CACL_N:
                # Force the dict to calculate and store the values
                s_dict.rel_inty(i_n, n)

        return s_dict

    @classmethod
    def load(cls, json_file):
        with open(json_file) as fh:
            return SpectraDict(json.load(fh))

    def save(self, json_file):
        with open(json_file, 'w') as fh:
            json.dump(self, fh)

        return self

现在,当使用rel_inty()函数询问值时,我们会立即将答案存储在自己体内,然后再返回。这称为记忆/缓存。因此,要用预先计算的值预先填充我们的对象,我们只需要问它许多答案,它就会存储它们

之后,我们可以使用JSON非常自然地加载或保存:

# Bootstrapping from scratch:
s_dict = SpectraDict().pre_calculate().save('spin_sys.json')

# Loading and updating with new values
s_dict = SpectraDict.load('spin_sys.json')
s_dict.rel_inty(10, 45)  # All your new calculations here...
s_dict.save('spin_sys.json')

相关问题 更多 >

    热门问题