将方法参数传递给过滤器列表的本地实例对象
pass method agument to local instance object for filter list
我想将 prent 方法中的参数转换为使用本地实例对象的过滤器来过滤列表结果。
这就是我大致想要的概念
def get_fields(path, editable=True): # If only editable (or opposite)
return list([f.name for f in fields(path) if f.editable]) # Do filter
def get_fields(path, required=True): # If only required (or opposite)
return list([f.name for f in fields(path) if f.required]) # Do filter
def get_fields(path): # If all
return list([f.name for f in fields(path)])
这就是我实际做的
def get_fields_editable(path):
return list(f.name for f in fields(path) if f.editable]))
def get_fields_required(path):
return list(f.name for f in fields(path) if f.required]))
def get_fields(path):
return list(f.name for f in fields(path)]))
我们可以使用 operator.attrgetter
从关键字参数名称和关联值创建合适的过滤函数。
为了演示此代码,我创建了一个简单的 Test
对象和一个 fields
函数。
from operator import attrgetter
def get_fields(path, **kwargs):
# Create the filter function
# Assumes there will only ever be at most a single keyword arg
if kwargs:
key, val = kwargs.popitem()
func = attrgetter(key)
filter_func = func if val else lambda obj: not func(obj)
else:
filter_func = lambda obj: True
return [f.name for f in fields(path) if filter_func(f)]
class Test(object):
def __init__(self, name, editable, required):
self.name = name
self.editable = editable
self.required = required
def fields(path):
return [
Test(path + '_a', False, False),
Test(path + '_b', False, True),
Test(path + '_c', True, False),
Test(path + '_d', True, True),
]
print(get_fields('none'))
print(get_fields('edfalse', editable=False))
print(get_fields('edtrue', editable=True))
print(get_fields('reqfalse', required=False))
print(get_fields('reqtrue', required=True))
输出
['none_a', 'none_b', 'none_c', 'none_d']
['edfalse_a', 'edfalse_b']
['edtrue_c', 'edtrue_d']
['reqfalse_a', 'reqfalse_c']
['reqtrue_b', 'reqtrue_d']
这是一个处理多个关键字的新版本。仅返回通过所有过滤器测试的项目。我稍微更改了测试对象名称并添加了一个 print
调用 get_fields
以便更容易地查看发生了什么。此代码适用于 Python 2 和 Python 3。
from __future__ import print_function
from operator import attrgetter
# Return items that pass any of the filters
def get_fields_any(path, **kwargs):
seq = fields(path)
print('KW', kwargs)
result = set()
if kwargs:
for key, val in kwargs.items():
# Create the filter function
func = attrgetter(key)
filter_func = func if val else lambda obj: not func(obj)
# Apply it
result.update(filter(filter_func, seq))
else:
result = seq
return [f.name for f in result]
# Only return items that pass all filters
def get_fields(path, **kwargs):
seq = fields(path)
print('KW', kwargs)
if kwargs:
for key, val in kwargs.items():
# Create the filter function
func = attrgetter(key)
filter_func = func if val else lambda obj: not func(obj)
# Apply it
seq = list(filter(filter_func, seq))
return [f.name for f in seq]
class Test(object):
def __init__(self, name, editable, required):
self.name = name
self.editable = editable
self.required = required
def __repr__(self):
fmt = 'Test({name}, {editable}, {required})'
return fmt.format(**self.__dict__)
def fields(path):
return [
Test(path + ':FF', False, False),
Test(path + ':FT', False, True),
Test(path + ':TF', True, False),
Test(path + ':TT', True, True),
]
print(get_fields('__'))
print(get_fields('_F', required=False))
print(get_fields('_T', required=True))
print(get_fields('F_', editable=False))
print(get_fields('T_', editable=True))
print()
print(get_fields('FF', editable=False, required=False))
print(get_fields('FT', editable=False, required=True))
print(get_fields('TF', editable=True, required=False))
print(get_fields('TT', editable=True, required=True))
输出
KW {}
['__:FF', '__:FT', '__:TF', '__:TT']
KW {'required': False}
['_F:FF', '_F:TF']
KW {'required': True}
['_T:FT', '_T:TT']
KW {'editable': False}
['F_:FF', 'F_:FT']
KW {'editable': True}
['T_:TF', 'T_:TT']
KW {'editable': False, 'required': False}
['FF:FF']
KW {'editable': False, 'required': True}
['FT:FT']
KW {'editable': True, 'required': False}
['TF:TF']
KW {'editable': True, 'required': True}
['TT:TT']
请注意,此代码可以处理任意数量的关键字,而不仅仅是两个。
我还包含了一个实验函数 get_fields_any
,其中 returns 通过 any 过滤器的对象。它使用集合 result
来累积匹配的对象,因此它不保留顺序。此外,将未定义 __eq__
和 __hash__
方法的对象放入集合中(或将它们用作 dict
键)是有风险的。有关详细信息,请参阅 __hash__ docs
。
我想将 prent 方法中的参数转换为使用本地实例对象的过滤器来过滤列表结果。
这就是我大致想要的概念
def get_fields(path, editable=True): # If only editable (or opposite)
return list([f.name for f in fields(path) if f.editable]) # Do filter
def get_fields(path, required=True): # If only required (or opposite)
return list([f.name for f in fields(path) if f.required]) # Do filter
def get_fields(path): # If all
return list([f.name for f in fields(path)])
这就是我实际做的
def get_fields_editable(path):
return list(f.name for f in fields(path) if f.editable]))
def get_fields_required(path):
return list(f.name for f in fields(path) if f.required]))
def get_fields(path):
return list(f.name for f in fields(path)]))
我们可以使用 operator.attrgetter
从关键字参数名称和关联值创建合适的过滤函数。
为了演示此代码,我创建了一个简单的 Test
对象和一个 fields
函数。
from operator import attrgetter
def get_fields(path, **kwargs):
# Create the filter function
# Assumes there will only ever be at most a single keyword arg
if kwargs:
key, val = kwargs.popitem()
func = attrgetter(key)
filter_func = func if val else lambda obj: not func(obj)
else:
filter_func = lambda obj: True
return [f.name for f in fields(path) if filter_func(f)]
class Test(object):
def __init__(self, name, editable, required):
self.name = name
self.editable = editable
self.required = required
def fields(path):
return [
Test(path + '_a', False, False),
Test(path + '_b', False, True),
Test(path + '_c', True, False),
Test(path + '_d', True, True),
]
print(get_fields('none'))
print(get_fields('edfalse', editable=False))
print(get_fields('edtrue', editable=True))
print(get_fields('reqfalse', required=False))
print(get_fields('reqtrue', required=True))
输出
['none_a', 'none_b', 'none_c', 'none_d']
['edfalse_a', 'edfalse_b']
['edtrue_c', 'edtrue_d']
['reqfalse_a', 'reqfalse_c']
['reqtrue_b', 'reqtrue_d']
这是一个处理多个关键字的新版本。仅返回通过所有过滤器测试的项目。我稍微更改了测试对象名称并添加了一个 print
调用 get_fields
以便更容易地查看发生了什么。此代码适用于 Python 2 和 Python 3。
from __future__ import print_function
from operator import attrgetter
# Return items that pass any of the filters
def get_fields_any(path, **kwargs):
seq = fields(path)
print('KW', kwargs)
result = set()
if kwargs:
for key, val in kwargs.items():
# Create the filter function
func = attrgetter(key)
filter_func = func if val else lambda obj: not func(obj)
# Apply it
result.update(filter(filter_func, seq))
else:
result = seq
return [f.name for f in result]
# Only return items that pass all filters
def get_fields(path, **kwargs):
seq = fields(path)
print('KW', kwargs)
if kwargs:
for key, val in kwargs.items():
# Create the filter function
func = attrgetter(key)
filter_func = func if val else lambda obj: not func(obj)
# Apply it
seq = list(filter(filter_func, seq))
return [f.name for f in seq]
class Test(object):
def __init__(self, name, editable, required):
self.name = name
self.editable = editable
self.required = required
def __repr__(self):
fmt = 'Test({name}, {editable}, {required})'
return fmt.format(**self.__dict__)
def fields(path):
return [
Test(path + ':FF', False, False),
Test(path + ':FT', False, True),
Test(path + ':TF', True, False),
Test(path + ':TT', True, True),
]
print(get_fields('__'))
print(get_fields('_F', required=False))
print(get_fields('_T', required=True))
print(get_fields('F_', editable=False))
print(get_fields('T_', editable=True))
print()
print(get_fields('FF', editable=False, required=False))
print(get_fields('FT', editable=False, required=True))
print(get_fields('TF', editable=True, required=False))
print(get_fields('TT', editable=True, required=True))
输出
KW {}
['__:FF', '__:FT', '__:TF', '__:TT']
KW {'required': False}
['_F:FF', '_F:TF']
KW {'required': True}
['_T:FT', '_T:TT']
KW {'editable': False}
['F_:FF', 'F_:FT']
KW {'editable': True}
['T_:TF', 'T_:TT']
KW {'editable': False, 'required': False}
['FF:FF']
KW {'editable': False, 'required': True}
['FT:FT']
KW {'editable': True, 'required': False}
['TF:TF']
KW {'editable': True, 'required': True}
['TT:TT']
请注意,此代码可以处理任意数量的关键字,而不仅仅是两个。
我还包含了一个实验函数 get_fields_any
,其中 returns 通过 any 过滤器的对象。它使用集合 result
来累积匹配的对象,因此它不保留顺序。此外,将未定义 __eq__
和 __hash__
方法的对象放入集合中(或将它们用作 dict
键)是有风险的。有关详细信息,请参阅 __hash__ docs
。