psy*_*ail 2 python oop python-3.x
我正在用 Python 3 编写一个类,我希望能够从用户那里获取各种关键字参数并存储这些值以供以后在类方法中使用。示例代码如下所示:
class MathematicalModel:
def __init__(self, var1, var2, var3, **kwargs):
self.var1 = var1
self.var2 = var2
self.var3 = var3
self.var4 = kwarg1
self.var5 = kwarg2
self.var6 = kwarg6
def calculation1(self):
x = self.var1 + self.var2 + self.var3
return x
def calculation2(self):
y = self.var1 * self.var2 * var3
return y
class MathematicalModelExtended(MathematicalModel):
def __init__(self, var1, var2, var3, **kwargs):
super.__init__(self, var1, var2, var3, **kwargs)
def calculation1(self):
'''Overrides calculation1 method from parent DoThis'''
x = (self.var1 + self.var2 + self.var3) / self.kwarg1
return x
def calculation2(self):
'''Overrides calculation2 method from parent DoThis'''
y = (self.var1 * self.var2 * self.var3) / (self.kwarg1 + self.kwarg2)
return y
a = MathematicalModel(1, 2, 3)
b = MathematicalModelExtended(1, 2, 3, var4 = 4, var5 = 5, var6 = 6)
Run Code Online (Sandbox Code Playgroud)
但是,我不确定这是如何工作的,原因如下:a) 如果用户没有为 b 或 c 设置参数,甚至没有为 a 设置参数怎么办?然后代码会抛出错误,所以我不确定在这种情况下如何初始化这些属性。b) 当我不知道用户事先传递的关键字参数是什么时,如何访问与关键字关联的值?
我计划在数学公式中使用这些变量。某些变量(未包含在 中kwargs)将在每个公式中使用,而其他变量(在 中的kwargs)将仅在其他公式中使用。为了实现这一目标,我计划MathematicalModel在另一个类中进行类似的包装MathematicalModelExtended(MathematicalModel)。
谢谢!
当您使用 加载变量时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) # 1
print(foo1.b) # 2
print(foo1.__dict__) # {'a': 1, 'b': 2}
Run Code Online (Sandbox Code Playgroud)
如果您想允许任意参数,您可以利用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) # 1
print(foo2.whatever_the_user_supplies) # 2
print(foo2.__dict__) # {'some_random_variable': 1, 'whatever_the_user_supplies': 2}
Run Code Online (Sandbox Code Playgroud)
这将防止您在尝试存储不存在的值时出错
class Foo3:
def __init__(self, **kwargs):
self.a = kwargs['a']
self.b = kwargs['b']
foo3 = Foo3(a=1) # KeyError: 'b'
Run Code Online (Sandbox Code Playgroud)
如果您想确保变量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) # 1
print(foo4.b) # None
print(foo4.__dict__) # {'a': 1, 'b': None}
Run Code Online (Sandbox Code Playgroud)
但是,使用此方法,变量属于类而不是实例。这就是为什么您会看到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) # 1
print(foo5.b) # Initial Value for B
print(foo5.__dict__) # {'a': 1}
Run Code Online (Sandbox Code Playgroud)
如果您让用户可以自由指定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()
# some_random_variable -> 1
# whatever_the_user_supplies -> 2
Run Code Online (Sandbox Code Playgroud)
但是,根据您在课堂上进行的其他任何事情,您最终可能会获得比用户提供的更多的实例属性。因此,让用户提供字典作为参数可能会很好。
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()
# some_random_variable -> 1
# whatever_the_user_supplies -> 2
Run Code Online (Sandbox Code Playgroud)
使用您更新的代码,我建议使用该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) # Store all the extra variables
class MathematicalModelExtended(MathematicalModel):
def __init__(self, var1, var2, var3, **kwargs):
super().__init__(var1, var2, var3, **kwargs)
def option1(self):
# Trap error if you need var4 to be specified
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):
# Use .get() to provide a default value when the user does not provide it.
_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()) # 1.5
print(b.option2()) # 1.5
Run Code Online (Sandbox Code Playgroud)
当然,如果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):
# Trap error if you need var4 to be specified
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):
# Use .get() to provide a default value when the user does not provide it.
_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()) # 1.5
print(b.option2()) # 1.5
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4294 次 |
| 最近记录: |