Python 重构处理“问题”的微小代码;“默认参数的覆盖”;
我有一个python(2.7)类,它结束了对一些bash命令的调用。这里重要的是,下面调用的那些命令需要向它们传递大量参数。这就是为什么我想允许在类的构造函数中设置这些参数,这种过于简单的做法如下所示:Python 重构处理“问题”的微小代码;“默认参数的覆盖”;,python,python-2.7,Python,Python 2.7,我有一个python(2.7)类,它结束了对一些bash命令的调用。这里重要的是,下面调用的那些命令需要向它们传递大量参数。这就是为什么我想允许在类的构造函数中设置这些参数,这种过于简单的做法如下所示: class Solution(object): _ALLOWED_USER = ['cake', 'chocolate', 'creme_brulee'] _ALLOWED_VARS = ['broccoli', 'avocado', 'spinach'] d
class Solution(object):
_ALLOWED_USER = ['cake', 'chocolate', 'creme_brulee']
_ALLOWED_VARS = ['broccoli', 'avocado', 'spinach']
def __init__(self, **kwargs):
self._validate_kwargs(kwargs)
for key, value in kwargs.iteritems():
setattr(self, '_{}'.format(key), value)
def _validate_kwargs(self, kwargs):
unrecognised = {key for key in kwargs if key not in self._ALLOWED_USER + self._ALLOWED_VARS}
if unrecognised:
raise ValueError('The following unrecognised arguments were passed: {}'.format(unrecognised))
def _populate(self, iterable, allowed, format_string):
result = []
for key in allowed:
attribute_name = '_{}'.format(key)
if key in iterable:
result.append(format_string.format(key, iterable[key]))
elif hasattr(self, attribute_name):
result.append(format_string.format(key, getattr(self, attribute_name)))
return result
def execute(self, **kwargs):
self._validate_kwargs(kwargs)
user_args = self._populate(kwargs, self._ALLOWED_USER, '--{}_param {}')
vars_args = self._populate(kwargs, self._ALLOWED_VARS, '--additional_param {}={}')
print(user_args + vars_args)
my_solution = Solution(cake='tasty', broccoli='icky', avocado='awesome')
my_solution.execute(creme_brulee='great', broccoli='okay, I guess', spinach='meh', cake='really tasty')
def\uuuu init\uuuu(self,foo=None,baz=None,bar=None):
self.\u executor=bash executor()
self.\u foo=foo
自。_baz=baz
自力杆=自力杆
此类还有一些函数,允许在一次bash执行的范围内重写这些参数(但不强制执行)。这意味着函数签名可以如下所示:
class Solution(object):
_ALLOWED_USER = ['cake', 'chocolate', 'creme_brulee']
_ALLOWED_VARS = ['broccoli', 'avocado', 'spinach']
def __init__(self, **kwargs):
self._validate_kwargs(kwargs)
for key, value in kwargs.iteritems():
setattr(self, '_{}'.format(key), value)
def _validate_kwargs(self, kwargs):
unrecognised = {key for key in kwargs if key not in self._ALLOWED_USER + self._ALLOWED_VARS}
if unrecognised:
raise ValueError('The following unrecognised arguments were passed: {}'.format(unrecognised))
def _populate(self, iterable, allowed, format_string):
result = []
for key in allowed:
attribute_name = '_{}'.format(key)
if key in iterable:
result.append(format_string.format(key, iterable[key]))
elif hasattr(self, attribute_name):
result.append(format_string.format(key, getattr(self, attribute_name)))
return result
def execute(self, **kwargs):
self._validate_kwargs(kwargs)
user_args = self._populate(kwargs, self._ALLOWED_USER, '--{}_param {}')
vars_args = self._populate(kwargs, self._ALLOWED_VARS, '--additional_param {}={}')
print(user_args + vars_args)
my_solution = Solution(cake='tasty', broccoli='icky', avocado='awesome')
my_solution.execute(creme_brulee='great', broccoli='okay, I guess', spinach='meh', cake='really tasty')
def执行(self,foo=None,baz=None,bar=None,sup=None):
然后是“有问题的部分”。每个参数都可以在函数的作用域中传递(在对象的构造函数中给定),也可以根本不传递(在函数中传递参数的优先级高于构造函数)。因此,我有以下代码片段:
foo=foo或self.\u foo
如果是foo:
params.append()
这仅仅是3行,但它们使用不同的参数重复了很多次,这些参数具有不同的格式
这难道不能简化吗
说明问题的完整示例如下所示:
类执行器(对象):
def执行(自我,命令):
打印命令
类示例(对象):
定义初始化(self,foo=None,baz=None,bar=None):
self.\u executor=bash executor()
self.\u foo=foo
自。_baz=baz
自力杆=自力杆
def执行(self,foo=None,baz=None,bar=None,sup=None):
参数=[]
foo=foo或self.\u foo
如果是foo:
参数追加(“--foo_参数%s”%foo)
baz=baz或self._baz
如果是baz:
参数追加(“--baz_参数%s”%baz)
bar=bar或self.\u bar
如果栏:
params.append(“--附加参数条=%s”%bar)
sup=sup或[]
如果支持:
params.append(“--附加参数sup=%s”%,”.join(sup))
self._executor.execute(“应用程序%s”%”“.join(参数))
ex=示例(foo=1,bar=2)
execute(foo=3,sup=[“abc”,“def”])
您可以这样做:
class Solution(object):
_ALLOWED_USER = ['cake', 'chocolate', 'creme_brulee']
_ALLOWED_VARS = ['broccoli', 'avocado', 'spinach']
def __init__(self, **kwargs):
self._validate_kwargs(kwargs)
for key, value in kwargs.iteritems():
setattr(self, '_{}'.format(key), value)
def _validate_kwargs(self, kwargs):
unrecognised = {key for key in kwargs if key not in self._ALLOWED_USER + self._ALLOWED_VARS}
if unrecognised:
raise ValueError('The following unrecognised arguments were passed: {}'.format(unrecognised))
def _populate(self, iterable, allowed, format_string):
result = []
for key in allowed:
attribute_name = '_{}'.format(key)
if key in iterable:
result.append(format_string.format(key, iterable[key]))
elif hasattr(self, attribute_name):
result.append(format_string.format(key, getattr(self, attribute_name)))
return result
def execute(self, **kwargs):
self._validate_kwargs(kwargs)
user_args = self._populate(kwargs, self._ALLOWED_USER, '--{}_param {}')
vars_args = self._populate(kwargs, self._ALLOWED_VARS, '--additional_param {}={}')
print(user_args + vars_args)
my_solution = Solution(cake='tasty', broccoli='icky', avocado='awesome')
my_solution.execute(creme_brulee='great', broccoli='okay, I guess', spinach='meh', cake='really tasty')
输出:
['--cake_param really tasty', '--creme_brulee_param great', '--additional_param broccoli=okay, I guess', '--additional_param avocado=awesome', '--additional_param spinach=meh']
您可以看到,cake
和brocoli
的实例值已被传递给函数的值覆盖
其基本思想是找出所有相关路径中的常数,并通过参数提供可定制性。通过将用户
参数与变量
参数分离,并使用**kwargs
,我们可以灵活地实现输入验证,并为每种类型的参数提供不同的输出
覆盖实例变量的参数的行为可以通过使用hasattr
首先检查传递的参数中是否存在每个参数,然后检查实例属性中是否存在每个参数来完成
我现在没有访问Python 2的权限,但这应该可以工作。您可以这样做:
class Solution(object):
_ALLOWED_USER = ['cake', 'chocolate', 'creme_brulee']
_ALLOWED_VARS = ['broccoli', 'avocado', 'spinach']
def __init__(self, **kwargs):
self._validate_kwargs(kwargs)
for key, value in kwargs.iteritems():
setattr(self, '_{}'.format(key), value)
def _validate_kwargs(self, kwargs):
unrecognised = {key for key in kwargs if key not in self._ALLOWED_USER + self._ALLOWED_VARS}
if unrecognised:
raise ValueError('The following unrecognised arguments were passed: {}'.format(unrecognised))
def _populate(self, iterable, allowed, format_string):
result = []
for key in allowed:
attribute_name = '_{}'.format(key)
if key in iterable:
result.append(format_string.format(key, iterable[key]))
elif hasattr(self, attribute_name):
result.append(format_string.format(key, getattr(self, attribute_name)))
return result
def execute(self, **kwargs):
self._validate_kwargs(kwargs)
user_args = self._populate(kwargs, self._ALLOWED_USER, '--{}_param {}')
vars_args = self._populate(kwargs, self._ALLOWED_VARS, '--additional_param {}={}')
print(user_args + vars_args)
my_solution = Solution(cake='tasty', broccoli='icky', avocado='awesome')
my_solution.execute(creme_brulee='great', broccoli='okay, I guess', spinach='meh', cake='really tasty')
输出:
['--cake_param really tasty', '--creme_brulee_param great', '--additional_param broccoli=okay, I guess', '--additional_param avocado=awesome', '--additional_param spinach=meh']
您可以看到,cake
和brocoli
的实例值已被传递给函数的值覆盖
其基本思想是找出所有相关路径中的常数,并通过参数提供可定制性。通过将用户
参数与变量
参数分离,并使用**kwargs
,我们可以灵活地实现输入验证,并为每种类型的参数提供不同的输出
覆盖实例变量的参数的行为可以通过使用hasattr
首先检查传递的参数中是否存在每个参数,然后检查实例属性中是否存在每个参数来完成
我现在没有访问Python 2的权限,但这应该可以使用。什么是“param”和“additional_param”的区别?这里没有任何内容(这是本例的弱点)。在现实生活中,我有一个函数execute
,可以接受user
和vars
参数。下面的Bash命令要求将用户作为--user%s
传递,并且在使用--extra vars
标志传递之前,需要将vars转储到json。是什么区别了“param”和“additional_param”?这里没有任何区别(这是本示例的弱点)。在现实生活中,我有一个函数execute
,可以接受user
和vars
参数。下面的Bash命令要求将用户作为--user%s
传递,并且在使用--extra-vars
标志传递之前,需要将vars转储到json。