【问题标题】:Create a python Class inheriting from a Class created by a function创建一个继承自函数创建的类的python类
【发布时间】:2021-08-23 07:50:54
【问题描述】:

什么有效:

我正在使用模块recordtype 来为我的程序的不同功能存储全局参数。

每个参数都是一个类实例:

class Parameter(object):

    def __init__(self, name, value, info):
        self.name = name
        self.value = value
        self.info = info

那么全局结构是这样定义的:

各个参数:

parameter_1 = Parameter('param_1', 10, 'Value for the parameter 1, usage...')
parameter_2 = Parameter('param_2', 20, 'Value for the parameter 2, usage...')
...
parameter_m = Parameter('param_n', 50, 'Value for the parameter m, usage...')
parameter_n = Parameter('param_n', 100, 'Value for the parameter n, usage...')

参数子集:

parameter_set_1 = recordtype('parameter_set_1', [(parameter_1.name, parameter_1), 
(parameter_2.name, parameter_2), ...])
...
parameter_set_n = recordtype('parameter_set_n', [(parameter_m.name, parameter_m), 
(parameter_n.name, parameter_n)]

那么全局参数结构是:

GlobalParametersFunction = recordtype('GlobalParameters', [('parameter_set_1', parameter_set_1()), 
('parameter_set_2', parameter_set_2()), ('parameter_set_n', parameter_set_n())])

需要实例化:

GlobalParameters = GlobalParameterFunction()

这一切都很好,GlobalParameterFunction 创建了一个类,我可以在其中访问各个参数并更改它们的值,例如:

GlobalParameters.parameter_set_1.parameter_1.value = 20

然后我可以从GlobalParameters 类实例创建一个打印值及其名称的函数:

def print_parameter_info(GP):
    for field, val in zip(GP._asdict(), GP._asdict().values()):
        print(field, ':')
        for key, entry in zip(val._asdict(), val._asdict().values()):
            print('\t', entry.name, ':', entry.value)

这对用户有好处:

>>> print_parameter_info(GlobalParameters)

parameter_set_1 :
     parameter_1 : 10
     parameter_2 : 20
parameter_set_n :
     parameter_m : 50
     parameter_n : 100

我还想创建一个这样的函数:

change(GlobalParameters, 'name', new_value)

做:

GlobalParameters.parameter_set_1.name.value = new_value

这对于recordtype创建的类似乎很容易实现

问题:

我想从print_parameter_info() 函数为GlobalParameters 类实例创建一个类方法,这样:

GlobalParameters.print_parameter_info()

GlobalParameters.change(name, new_value)

作品

因为GlobalParametersrecordtype的类实例,所以我试过了:

class GlobalParameterClass(recordtype):
    
    def __init__(self):
        self = GlobalParameterFunction()

但是因为recordtype 是一个创建类的函数? 我收到以下错误:

TypeError: function() argument 'code' must be code, not str

我找到了这个question (2231427)

但是在尝试导入正确的东西并查看recordtype的源代码后,我想我明白recordtype没有明确定义class并通过解析一串代码来创建它?

因此我不明白如何创建一个继承自recordtype创建的类的类

我也试过

class GlobalParameterClass(object):

    def __init__(self, *args):
        self = GlobalParameterFunction(*args)

这不会引发任何错误,但创建的类实例是空的。

TLDR/结论

如何向recordtype 模块中的recordtype 函数创建的类添加自定义方法?

或者

或许有更好的方法来管理 GlobalParameters 对象?

谢谢!

【问题讨论】:

    标签: python-3.x class inheritance recordtype


    【解决方案1】:

    通过创建具有所需行为的自定义类,我找到了一个不使用 recordtype 对象的解决方案:

    class Parameter(object):
        """
        A class to store the individual sound parameters
        """
        def __init__(self, name, value, info):
            self.name = name
            self.value = value
            self.info = info
    
    class ParameterSet(object):
        """
        A class to store multiple parameters as a set
        """
        def __init__(self, name, *parameters):
            self.name = name
            for parameter in parameters:
                setattr(self, parameter.name, parameter)
    
    class GlobalParameters(object):
        """
        A class to store the parameter sets and to be used to assign parameter values to the different functions
        """
        def __init__(self, *parameter_sets):
            for parameter_set in parameter_sets:
                setattr(self, parameter_set.name, parameter_set)
    

    GlobalParameters 类的方法如下:

        def info(self):
            for parameter_set in self.__dict__.values():
                print(parameter_set.name)
                parameters = [parameter for parameter in parameter_set_1.__dict__.values() if type(parameter) != str]
                for parameter in parameters:
                    print('\t', parameter.name, ':', parameter.value)
                    
        def change(self, name, value):
            for parameter_set in self.__dict__.values():
                parameters = [parameter for parameter in parameter_set_1.__dict__.values() if type(parameter) != str]
                for parameter  in parameters:
                    if parameter.name == name:
                        parameter.value = value
    

    使用此示例代码:

    # Individual parameters
    parameter_1 = Parameter('parameter_1', 10, 'Value for the parameter 1, usage...')
    parameter_2 = Parameter('parameter_2', 20, 'Value for the parameter 2, usage...')
    parameter_n = Parameter('parameter_n', 50, 'Value for the parameter n, usage...')
    parameter_m = Parameter('parameter_m', 100, 'Value for the parameter m, usage...')
    
    # Parameter sets
    parameter_set_1 = ParameterSet('parameter_set_1', parameter_1, parameter_2)
    parameter_set_2 = ParameterSet('parameter_set_n', parameter_n, parameter_m)
    
    # Global parameter set
    GP = GlobalParameters(parameter_set_1, parameter_set_2)
    

    我得到了想要的行为:

    >>> GP.info()
    parameter_set_1
         parameter_1 : 10
         parameter_2 : 20
    parameter_set_n
         parameter_1 : 10
         parameter_2 : 20
    

    以及.change 方法:

    >>> GP.parameter_set_1.parameter_1.value
    10
    
    GP.change('parameter_1', 15)
    
    >>> GP.parameter_set_1.parameter_1.value
    15
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-30
      • 2018-10-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多