我想将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)]))
答案 0 :(得分:0)
我们可以使用operator.attrgetter
从关键字arg名称和相关值创建合适的过滤函数。
为了演示此代码,我创建了一个简单的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
,它返回传递任何过滤器的对象。它使用集合result
来累积匹配的对象,因此它不会保留顺序。此外,将未定义__eq__
和__hash__
方法的对象放入集合(或将它们用作dict
键)是有风险的。有关详细信息,请参阅__hash__ docs
。