Python Class 中的条件语句
Python conditional statement within a Class
根据通过 cli 参数传入的输入,实现 class 属性发生变化的最佳方法是什么?
我写的东西工作得很好,但感觉过于混乱和糟糕的设计。有没有更好的方法来解决这个问题?
下面的例子有四个不同的输入,但是随着这个程序变大,它会变得非常混乱。
这是一些简短的示例代码;
class Example(object):
def __init__(self, var1):
self.var1 = var1
self.var2 = None
self.var3 = None
self.var4 = None
if var1 == 'foo':
self.var2 = 'foo2'
self.var3 = 'foo3'
self.var4 = 'foo4'
elif var1 == 'bar':
self.var2 = 'bar2'
self.var3 = 'bar3'
self.var4 = 'bar4'
elif var1 == 'foobar':
self.var2 = 'foobar2'
self.var3 = 'foobar3'
self.var4 = 'foobar4'
elif var1 == 'barfoo':
self.var2 = 'barfoo2'
self.var3 = 'barfoo3'
self.var4 = 'barfoo4'
def main()
parser = argparse.ArgumentParser()
parser.add_argument('input')
args = parser.parse_args()
example = Example(args.input)
print(example.var2) # returns 'foo2'
带参数调用的示例;
python main.py foo
不知道是否是最佳选择,但假设实际值是 'foo1' 'foo2'
但其他或更复杂的东西我会去更新自我。dict
两种方式(我觉得第二种更清楚)
class A():
def __init__(self,var1):
self.var1 = var1
fooDict = {'var2':'foo2','var3':'foo3','var4':'foo4'}
foovarDict = {'var2':'foovar2','var3':'foovar3','var4':'foovar4'}
if var1 == 'foo':
self.__dict__ = {**self.__dict__,**fooDict}
elif var1 == 'foovar':
self.__dict__ = {**self.__dict__,**foovarDict}
def getVars(self):
print(self.var1)
print(self.var2)
print(self.var3)
print(self.var4)
a = A('foo')
a.getVars()
#ouputs
#foo
#foo2
#foo3
#foo4
b = A('foovar')
b.getVars()
#outputs
#foovar
#foovar2
#foovar3
#foovar4
第二种方式:
class A():
def __init__(self,var1):
self.var1 = var1
fooDict = {'var2':'foo2','var3':'foo3','var4':'foo4'}
foovarDict = {'var2':'foovar2','var3':'foovar3','var4':'foovar4'}
if var1 == 'foo':
self.__dict__.update(fooDict)
elif var1 == 'foovar':
self.__dict__.update(foovarDict)
def getVars(self):
print(self.var1)
print(self.var2)
print(self.var3)
print(self.var4)
a = A('foo')
a.getVars()
b = A('foovar')
b.getVars()
具有相同的输出
如评论中所建议的,有很多方法可以清理它。对于您示例的大小和规模,我会做这样的事情:
class Example:
_DEPENDENT_VALS = {
'foo': ('foo2', 'foo3', 'foo4'),
'bar': ('bar2', 'bar3', 'bar4'),
'foobar': ('foobar2', 'foobar3', 'foobar4'),
'barfoo': ('barfoo2', 'barfoo3', 'barfoo4')
}
def __init__(self, var1):
self.var1 = var1
self.var2 = None
self.var3 = None
self.var4 = None
if var1 in Example._DEPENDENT_VALS:
self.var2, self.var3, self.var4 = Example._DEPENDENT_VALS[var1]
根据您设置的值的数量和类型,此方法可能并不总是合适的,但这是一种解决方法。
ls=['foo','bar','foobar','barfoo'] #adds the list of prefixes
if self.var1 in ls:
self.var2= f'{self.var1}2'
self.var3= f'{self.var1}3'
self.var4= f'{self.var1}4'
定义一个dict
映射前缀到三个修饰符中的一个tuple
,然后用它来初始化它们:
class Example:
_var_suffixes = {'foo': ('1', '2', '3'),
'bar': ('1', '2', '3'),
'foobar': ('1', '2', '3'),
'barfoo': ('1', '2', '3'),
}
def __init__(self, var1):
self.var1 = var1
self.var2 = None
self.var3 = None
self.var4 = None
if var1 in self._var_suffixes:
suf2, suf3, suf4 = self._var_suffixes[var1]
self.var2 = var1 + suf2
self.var3 = var1 + suf3
self.var4 = var1 + suf4
可选地,将 var2
到 var4
存储为 list
可能更有意义(特别是如果后缀的数量是按键可变的),在这种情况下你d 做这样的事情,这更简单:
class Example:
_var_suffixes = {'foo': ('1', '2'),
'bar': ('1', '2', '3'),
'foobar': ('1', '2', '3', '4'),
'barfoo': ('1', '2', '3', '4', '5'),
}
def __init__(self, var1):
self.var1 = var1
self.varlist = []
for suf in self._var_suffixes.get(var1, ()):
self.varlist.append(var1 + suf)
# Optional property for access by name
@property
def var2(self):
try:
return self.varlist[0]
except IndexError:
return None
class 主体只是 Python 代码。它有特定的范围规则,但一切都不一样。这意味着您可以有条件地创建函数:
class C:
if some_condition:
def optional_method(self):
pass
或从别处拉取方法:
import some_module
class D:
method_name = some_module.function_that_accepts_self
一种方法是让 __init__
尽可能“愚蠢”,为对象的每个“样式”定义单独的 class 方法,并减轻选择正确 class 的负担] 调用调用方的方法。
class Example:
def __init__(self, var1, var2, var3, var4):
self.var1 = var1
self.var2 = var2
self.var3 = var3
self.var4 = var4
@classmethod
def foo(cls):
return cls('foo', 'foo2', 'foo3', 'foo4')
@classmethod
def bar(cls):
return cls('bar', 'bar2', 'bar3', 'bar4')
# etc
# Instead of Example('foo')
e = Example.foo()
您在这里唯一失去的是将未知值传递给 Example
并返回正确初始化值的能力,例如,
x = "..." # Assumed to be foo, bar, foobar, or barfoo
e = Example(x)
但是,调用者始终可以使用您可能隐藏在 Element.__init__
中的任何方法来为 var2
等选择值。为所有人选择哪种 class 方法。例如,
x = "foo"
e = getattr(Example, x)() # e = Example.foo()
根据通过 cli 参数传入的输入,实现 class 属性发生变化的最佳方法是什么?
我写的东西工作得很好,但感觉过于混乱和糟糕的设计。有没有更好的方法来解决这个问题?
下面的例子有四个不同的输入,但是随着这个程序变大,它会变得非常混乱。
这是一些简短的示例代码;
class Example(object):
def __init__(self, var1):
self.var1 = var1
self.var2 = None
self.var3 = None
self.var4 = None
if var1 == 'foo':
self.var2 = 'foo2'
self.var3 = 'foo3'
self.var4 = 'foo4'
elif var1 == 'bar':
self.var2 = 'bar2'
self.var3 = 'bar3'
self.var4 = 'bar4'
elif var1 == 'foobar':
self.var2 = 'foobar2'
self.var3 = 'foobar3'
self.var4 = 'foobar4'
elif var1 == 'barfoo':
self.var2 = 'barfoo2'
self.var3 = 'barfoo3'
self.var4 = 'barfoo4'
def main()
parser = argparse.ArgumentParser()
parser.add_argument('input')
args = parser.parse_args()
example = Example(args.input)
print(example.var2) # returns 'foo2'
带参数调用的示例;
python main.py foo
不知道是否是最佳选择,但假设实际值是 'foo1' 'foo2'
但其他或更复杂的东西我会去更新自我。dict
两种方式(我觉得第二种更清楚)
class A():
def __init__(self,var1):
self.var1 = var1
fooDict = {'var2':'foo2','var3':'foo3','var4':'foo4'}
foovarDict = {'var2':'foovar2','var3':'foovar3','var4':'foovar4'}
if var1 == 'foo':
self.__dict__ = {**self.__dict__,**fooDict}
elif var1 == 'foovar':
self.__dict__ = {**self.__dict__,**foovarDict}
def getVars(self):
print(self.var1)
print(self.var2)
print(self.var3)
print(self.var4)
a = A('foo')
a.getVars()
#ouputs
#foo
#foo2
#foo3
#foo4
b = A('foovar')
b.getVars()
#outputs
#foovar
#foovar2
#foovar3
#foovar4
第二种方式:
class A():
def __init__(self,var1):
self.var1 = var1
fooDict = {'var2':'foo2','var3':'foo3','var4':'foo4'}
foovarDict = {'var2':'foovar2','var3':'foovar3','var4':'foovar4'}
if var1 == 'foo':
self.__dict__.update(fooDict)
elif var1 == 'foovar':
self.__dict__.update(foovarDict)
def getVars(self):
print(self.var1)
print(self.var2)
print(self.var3)
print(self.var4)
a = A('foo')
a.getVars()
b = A('foovar')
b.getVars()
具有相同的输出
如评论中所建议的,有很多方法可以清理它。对于您示例的大小和规模,我会做这样的事情:
class Example:
_DEPENDENT_VALS = {
'foo': ('foo2', 'foo3', 'foo4'),
'bar': ('bar2', 'bar3', 'bar4'),
'foobar': ('foobar2', 'foobar3', 'foobar4'),
'barfoo': ('barfoo2', 'barfoo3', 'barfoo4')
}
def __init__(self, var1):
self.var1 = var1
self.var2 = None
self.var3 = None
self.var4 = None
if var1 in Example._DEPENDENT_VALS:
self.var2, self.var3, self.var4 = Example._DEPENDENT_VALS[var1]
根据您设置的值的数量和类型,此方法可能并不总是合适的,但这是一种解决方法。
ls=['foo','bar','foobar','barfoo'] #adds the list of prefixes
if self.var1 in ls:
self.var2= f'{self.var1}2'
self.var3= f'{self.var1}3'
self.var4= f'{self.var1}4'
定义一个dict
映射前缀到三个修饰符中的一个tuple
,然后用它来初始化它们:
class Example:
_var_suffixes = {'foo': ('1', '2', '3'),
'bar': ('1', '2', '3'),
'foobar': ('1', '2', '3'),
'barfoo': ('1', '2', '3'),
}
def __init__(self, var1):
self.var1 = var1
self.var2 = None
self.var3 = None
self.var4 = None
if var1 in self._var_suffixes:
suf2, suf3, suf4 = self._var_suffixes[var1]
self.var2 = var1 + suf2
self.var3 = var1 + suf3
self.var4 = var1 + suf4
可选地,将 var2
到 var4
存储为 list
可能更有意义(特别是如果后缀的数量是按键可变的),在这种情况下你d 做这样的事情,这更简单:
class Example:
_var_suffixes = {'foo': ('1', '2'),
'bar': ('1', '2', '3'),
'foobar': ('1', '2', '3', '4'),
'barfoo': ('1', '2', '3', '4', '5'),
}
def __init__(self, var1):
self.var1 = var1
self.varlist = []
for suf in self._var_suffixes.get(var1, ()):
self.varlist.append(var1 + suf)
# Optional property for access by name
@property
def var2(self):
try:
return self.varlist[0]
except IndexError:
return None
class 主体只是 Python 代码。它有特定的范围规则,但一切都不一样。这意味着您可以有条件地创建函数:
class C:
if some_condition:
def optional_method(self):
pass
或从别处拉取方法:
import some_module
class D:
method_name = some_module.function_that_accepts_self
一种方法是让 __init__
尽可能“愚蠢”,为对象的每个“样式”定义单独的 class 方法,并减轻选择正确 class 的负担] 调用调用方的方法。
class Example:
def __init__(self, var1, var2, var3, var4):
self.var1 = var1
self.var2 = var2
self.var3 = var3
self.var4 = var4
@classmethod
def foo(cls):
return cls('foo', 'foo2', 'foo3', 'foo4')
@classmethod
def bar(cls):
return cls('bar', 'bar2', 'bar3', 'bar4')
# etc
# Instead of Example('foo')
e = Example.foo()
您在这里唯一失去的是将未知值传递给 Example
并返回正确初始化值的能力,例如,
x = "..." # Assumed to be foo, bar, foobar, or barfoo
e = Example(x)
但是,调用者始终可以使用您可能隐藏在 Element.__init__
中的任何方法来为 var2
等选择值。为所有人选择哪种 class 方法。例如,
x = "foo"
e = getattr(Example, x)() # e = Example.foo()