Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 存储类及其子类的init参数_Python_Python 3.x_Class_Python Decorators - Fatal编程技术网

Python 存储类及其子类的init参数

Python 存储类及其子类的init参数,python,python-3.x,class,python-decorators,Python,Python 3.x,Class,Python Decorators,我有一个类,我希望能够存储在创建该类或任何子类(子类init的参数比超类多)的新实例时给出的参数的名称和值 目前我用这个函数装饰我所有子类的init,这就是我的工作。 但是,有没有一种方法可以在不装饰每个init的情况下获得相同的效果? 环顾四周,我看到元类做了一些类似的事情,但我从来没有使用过它们,我也找不到一种方法在这里应用它们 提前谢谢 您不需要更改为仅使用关键字args,也可以捕获位置。或多或少,您将适应任何存储和访问args的方式: class C: def __init__(

我有一个类,我希望能够存储在创建该类或任何子类(子类init的参数比超类多)的新实例时给出的参数的名称和值

目前我用这个函数装饰我所有子类的init,这就是我的工作。 但是,有没有一种方法可以在不装饰每个init的情况下获得相同的效果? 环顾四周,我看到元类做了一些类似的事情,但我从来没有使用过它们,我也找不到一种方法在这里应用它们


提前谢谢

您不需要更改为仅使用关键字args,也可以捕获位置。或多或少,您将适应任何存储和访问args的方式:

class C:
    def __init__(self, *args, **kwargs):
        self.called_with = dict(
            name = self.__class__,
            positionals = args,
            keywords = kwargs
            )
        print(args, kwargs)

class D(C):
    pass

c1 = C(1,2,3,a='A',b='B')
print(c1.called_with['name'])
print(c1.called_with['positionals'])
print(c1.called_with['keywords'])

print()

d1 = D(1,2,3,4,d='D')
print(d1.called_with['name'])
print(d1.called_with['positionals'])
print(d1.called_with['keywords'])
输出:

(1, 2, 3) {'a': 'A', 'b': 'B'}
<class '__main__.C'>
(1, 2, 3)
{'a': 'A', 'b': 'B'}

(1, 2, 3, 4) {'d': 'D'}
<class '__main__.D'>
(1, 2, 3, 4)
{'d': 'D'}
'{'a1': 1, 'a2': 2, 'Problem': 'B'}'

此解决方案不起作用,因为我也想存储args名称 当前版本影响的ex: 声明:

class A:
    def __init__(self, x):
        self.x = x

class B(A):
    @init_store
    def __init__(self, a1, a2):
        self.a1, self.a2 = a1, a2
        super(B, self).__init__(True)
电话:

b = B(1, 2)
print(b.init_values)
输出:

(1, 2, 3) {'a': 'A', 'b': 'B'}
<class '__main__.C'>
(1, 2, 3)
{'a': 'A', 'b': 'B'}

(1, 2, 3, 4) {'d': 'D'}
<class '__main__.D'>
(1, 2, 3, 4)
{'d': 'D'}
'{'a1': 1, 'a2': 2, 'Problem': 'B'}'

如果您将类设计为只使用关键字参数,这似乎会简单得多;然后,您只需要子类将其所有参数传递给
super()。\uuuuu init\uuuuu
,您的基类
\uuuuuuuu init\uuuuuu
就可以简单地保存
**kwargs
,而无需修饰任何方法。是的,这种方法非常有效,但我更愿意不必将我的类更改为只使用kwargsWhy<如果不必考虑参数传递给各种方法的顺序,则代码>超级更容易正确使用。主类只有一个,但每个子类可能会引入冲突的位置参数。关键字参数标识它们自己,并且不依赖于它们的传递顺序。@vjhjj请参见我的编辑。如果您开始有子类引入它们自己的位置参数,则使用位置参数会变得混乱。假设
A
有一个参数,
B
C
各自继承自
A
并添加自己的第二个参数,然后
D
继承自
B
C
。如何解释
D(1,2,3)
?我没有这个问题,因为super的唯一参数取决于我所处的子类,而不是在创建子类实例时使用的参数sublcass init看起来像:``def uu init uu(self,*args):`Use args super()。`uu_uinit uu(True)```@chepner,你是对的,你的评论“主类只有一个,但是……”使你的观点非常清楚。我只是没有得到这一切的行动意图。我看你的例子很简单。具有这些位置的D实例。你想对他们做什么就做什么。把它们传给super时也是一样。是的,这太傻了。它意味着一个类知道它在层次结构中的位置以选择合适的参数。这就把这些课程和太多的知识联系起来了。我从来不需要写这样的代码(但那只是我自己),这就是为什么我没有考虑太多。我正在编辑我的答案。如果你想存储arg名称,你是说你需要在实例创建调用中使用关键字args。