有没有办法阻止某些但不是所有的参数被发送到超类?你知道吗
我有一个验证用户输入的基类:
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
被传递给超类,即使它只在子类中是必需的。但是,a
和b
参数用于A
,应该从B
传递到A
。你知道吗
是的,很简单:不要通过。你应该知道你的类接受哪些参数,以及它的超类也接受哪些参数,所以只传递超类所期望的:
以上内容简单易读,易于维护,并保证正常工作。如果你想要默认值也不是问题:
现在,如果类的职责是根据给定的“模式”(代码段中的
default_properties
)验证任意用户输入,那么代码中确实存在两个逻辑错误—主要是1。验证初始值设定项和2中的输入。在重写对象的default_properties
之前调用父类的初始值设定项,因此当调用超类初始值设定项时,它不会根据正确的模式进行验证。另外,您正在将default_properties
定义为初始值设定项中的实例属性,因此,如果您只是交换指令,先定义default_propertie
,然后才调用父级的初始值设定项,那么这个将重新定义default_properties
一个简单的解决方法是将
default_properties
设为类属性:然后你就不必重写初始值设定项了:
完成了-
check_integrity
将使用当前实例的类default_properties
,您不必关心“对传递给超类的kwarg进行选择”。你知道吗现在这仍然是一种简单化的方法,可以有效地作为输入验证framewoek工作,特别是如果您想要继承的话。。。如果
B
是A
的适当子类,那么它应该能够添加到default_properties
,而不必完全重新定义它(这是一个明显的干冲突)。用户输入验证通常比检查参数名要复杂得多。。。您可能想研究其他libs/框架是如何解决这个问题的(这里想到的是Django的表单)。你知道吗相关问题 更多 >
编程相关推荐