通用kwargs想法
当您使用self.var = value
加载变量时,它会将其添加到内部字典中,可以使用self.__dict__
访问它。
class Foo1:
def __init__(self, **kwargs):
self.a = kwargs['a']
self.b = kwargs['b']
foo1 = Foo1(a=1, b=2)
print(foo1.a)
print(foo1.b)
print(foo1.__dict__)
如果您想允许任意参数,您可以利用 kwargs
也是一个字典的事实,并使用 update()
函数。
class Foo2:
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
foo2 = Foo2(some_random_variable=1, whatever_the_user_supplies=2)
print(foo2.some_random_variable)
print(foo2.whatever_the_user_supplies)
print(foo2.__dict__)
这将防止您在尝试存储不存在的值时出现错误。
class Foo3:
def __init__(self, **kwargs):
self.a = kwargs['a']
self.b = kwargs['b']
foo3 = Foo3(a=1)
如果您想确保类中的变量a
或b
被设置,而不管用户提供了什么,您可以创建类属性或使用kwargs.get()
。
class Foo4:
def __init__(self, **kwargs):
self.a = kwargs.get('a', None)
self.b = kwargs.get('b', None)
foo4 = Foo4(a=1)
print(foo4.a)
print(foo4.b)
print(foo4.__dict__)
然而,使用这种方法,变量属于类而不是实例。这就是为什么你会看到foo5.b
返回一个字符串,但它并不在foo5.__dict__
中。
class Foo5:
a = 'Initial Value for A'
b = 'Initial Value for B'
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
foo5 = Foo5(a=1)
print(foo5.a)
print(foo5.b)
print(foo5.__dict__)
如果您允许用户自由指定任何kwargs
,则可以在函数中遍历__dict__
。
class Foo6:
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
def do_something(self):
for k, v in self.__dict__.items():
print(f"{k} -> {v}")
foo6 = Foo6(some_random_variable=1, whatever_the_user_supplies=2)
foo6.do_something()
然而,根据您在课堂上的其他活动,您可能会拥有比用户提供的更多的实例属性。因此,最好让用户提供一个字典作为参数。
class Foo7:
def __init__(self, user_vars):
self.user_vars = user_vars
def do_something(self):
for k, v in self.user_vars.items():
print(f"{k} -> {v}")
foo7 = Foo7({'some_random_variable': 1, 'whatever_the_user_supplies': 2})
foo7.do_something()
处理你的代码
使用更新后的代码,我建议使用self.__dict__.update(kwargs)
方法。然后当你依赖的变量没有遇到时,你可以抛出一个错误(option1
方法),或者你可以为该变量设置一个默认值以防未定义(option2
方法)。
class MathematicalModel:
def __init__(self, var1, var2, var3, **kwargs):
self.var1 = var1
self.var2 = var2
self.var3 = var3
self.__dict__.update(kwargs)
class MathematicalModelExtended(MathematicalModel):
def __init__(self, var1, var2, var3, **kwargs):
super().__init__(var1, var2, var3, **kwargs)
def option1(self):
if 'var4' not in self.__dict__:
raise ValueError("Please provide value for var4")
x = (self.var1 + self.var2 + self.var3) / self.var4
return x
def option2(self):
_var4 = self.__dict__.get('var4', 1)
x = (self.var1 + self.var2 + self.var3) / self.var4
return x
a = MathematicalModel(1, 2, 3)
b = MathematicalModelExtended(1, 2, 3, var4=4, var5=5, var6=6)
print(b.option1())
print(b.option2())
如果 MathematicalModel
永远只使用 var1
、var2
和 var3
,那么传递 kwargs
是没有意义的。
class MathematicalModel:
def __init__(self, var1, var2, var3, **kwargs):
self.var1 = var1
self.var2 = var2
self.var3 = var3
class MathematicalModelExtended(MathematicalModel):
def __init__(self, var1, var2, var3, **kwargs):
super().__init__(var1, var2, var3)
self.__dict__.update(kwargs)
def option1(self):
if 'var4' not in self.__dict__:
raise ValueError("Please provide value for var4")
x = (self.var1 + self.var2 + self.var3) / self.var4
return x
def option2(self):
_var4 = self.__dict__.get('var4', 1)
x = (self.var1 + self.var2 + self.var3) / self.var4
return x
a = MathematicalModel(1, 2, 3)
b = MathematicalModelExtended(1, 2, 3, var4=4, var5=5, var6=6)
print(b.option1())
print(b.option2())
a
、b
和c
代表什么?同样地,key1
、key2
和key3
又代表什么?你是在寻找*args
还是**kwargs
? - CohanDoThis
和NowDoThis
这样的类应该做什么以及它们如何被调用或使用。拥有通用函数和类具有很大的价值,但在这种情况下,缺乏清晰度使得很难为您的问题提供一个好的答案。 - Cohan**kwargs
是可变数量的关键字参数 - 这意味着它们的数量是任意的。使用kwargs
的显式字段,例如self.kwarg1
,没有任何意义 -**kwargs
的要点在于每个特定的关键字参数可能存在也可能不存在。换句话说,如果您期望一个特定的kwarg1
,那么它就不是可变的定义。 - MisterMiyagikwargs
,以展示我想要如何使用这些参数。谢谢你的评论。 - psychedelic-snail