gpt4 book ai didi

python - 是否可以选择将哪些 kwargs 传递给 python 中的父类(super class)?

转载 作者:行者123 更新时间:2023-11-30 22:31:11 24 4
gpt4 key购买 nike

有没有办法阻止部分但不是全部参数被发送到父类(super class)?

我有一个验证用户输入的基类:

class Base(object):
def __init__(self, **kwargs):
self.kwargs = kwargs
super(Base, self).__init__()

@staticmethod
def check_integrity(allowed, given):
"""
Verify user input.
:param allowed: list. Keys allowed in class
:param given: list. Keys given by user
:return:
"""
for key in given:
if key not in allowed:
raise Exception('{} not in {}'.format(key, allowed))

>>> base = Base()
>>> print base.__dict__
output[0]: {'kwargs': {}}

A继承自Base并使用该方法检查其关键字

class A(Base):
def __init__(self, **kwargs):
super(A, self).__init__(**kwargs)
self.default_properties = {'a': 1,
'b': 2}

self.check_integrity(self.default_properties.keys(), kwargs.keys())

>>> a = A(a=4)
>>> print a.__dict__
output[1]: {'default_properties': {'a': 1, 'b': 2}, 'kwargs': {'a': 4}}

我还应该提到,我已经提取了在此类中用于更新类属性的另一种方法,因为它的复杂性与问题无关(因此为什么 a 没有更新为上面的 4示例)

尝试继承 A 时会出现问题。并添加额外的 kwargs到子类:

class B(A):
def __init__(self, **kwargs):
super(B, self).__init__(**kwargs)

self.default_properties = {'a': 2,
'c': 3,
'd': 4}

self.check_integrity(self.default_properties.keys(), kwargs.keys())



>>> b = B(d=5)


Traceback (most recent call last):
File "/home/b3053674/Documents/PyCoTools/PyCoTools/Tests/scrap_paper.py", line 112, in <module>
b = B(d=5)
File "/home/b3053674/Documents/PyCoTools/PyCoTools/Tests/scrap_paper.py", line 96, in __init__
super(B, self).__init__(**kwargs)
File "/home/b3053674/Documents/PyCoTools/PyCoTools/Tests/scrap_paper.py", line 92, in __init__
self.check_integrity(self.default_properties.keys(), kwargs.keys())
File "/home/b3053674/Documents/PyCoTools/PyCoTools/Tests/scrap_paper.py", line 84, in check_integrity
raise Exception('{} not in {}'.format(key, allowed))
Exception: d not in ['a', 'b']

这里d被传递给父类(super class),即使它只在子类中需要。然而,ab参数用于 A并且应该从 B 传递至A

最佳答案

Is there a way to prevent some but not all arguments from being sent up to a superclass?

嗯,是的,很简单:不要超越它们。您应该知道您的类采用哪些参数以及它的父类(super class)也采用哪些参数,因此仅传递父类(super class)期望的参数:

class Base(object):
def __init__(self, arg1, arg2):
self.arg1 = arg1
self.arg2 = arg2

class Child(object):
def __init__(self, arg1, arg2, arg3):
super(Child, self).__init__(arg1, arg2)
self.arg3 = arg3

上面的内容非常简单,可读且可维护,并且保证可以工作。如果您想要默认值,这也不是问题:

class Base(object):
def __init__(self, arg1=1, arg2=2):
self.arg1 = arg1
self.arg2 = arg2

class Child(object):
def __init__(self, arg1=1, arg2=2, arg3=3):
super(Child, self).__init__(arg1, arg2)
self.arg3 = arg3

现在,如果您的类的职责是根据给定的“架构”(代码片段中的 default_properties)验证任意用户输入,那么您的代码中确实存在一些逻辑错误 - 主要是您 1 . 验证您在初始化程序中的输入,并 2. 在覆盖对象的 default_properties 之前调用父级的初始化程序,因此当调用父类(super class)初始化程序时,它不会根据正确的架构进行验证。另外,您将 default_properties 定义为初始化程序中的实例属性,因此,如果您只是交换指令以首先定义 default_propertie ,然后调用父级的初始化程序,则此初始化程序将重新定义 default_properties

一个简单的修复方法是将 default_properties 设为类属性:

class Base(object):

# empty by default
default_properties = {}

def __init__(self, **kwargs):
self.kwargs = kwargs
# object.__init__ is a noop so no need for a super call here
self.check_integrity()

def check_integrity(self):
"""
Verify user input.
"""
for key in self.kwargs:
if key not in self.default_properties:
raise ValueError('{} not allowed in {}'.format(key, self.default_properties))

然后您根本不必重写初始化程序:

class A(Base):
default_properties = {'a': 1,
'b': 2}


class B(A):
default_properties = {'a': 1,
'b': 2,
'd': 3}

你就完成了 - check_integrity 将使用当前实例的类 default_properties 并且你不必关心“选择性地传递给父类(super class)”。

现在,这仍然是作为输入验证框架有效工作的简单方法,特别是如果您想要继承......如果 BA 的正确子类,它应该能够添加到 default_properties 而不必完全重新定义它(这是明显的 DRY 违规)。用户输入验证通常比仅仅检查参数名称要复杂得多...您可能想研究其他库/框架如何解决问题(这里想到了 Django 的表单)。

关于python - 是否可以选择将哪些 kwargs 传递给 python 中的父类(super class)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45879173/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com