面向对象编程中创建列表和过滤不同结果的好方法是什么?
我有一个方法可以创建一个目录下文件的列表,但我还有多个其他方法也能做到这一点,并且在循环中会进行一些额外的过滤。
我觉得这样做看起来很糟糕,我很想知道有没有更优雅的解决办法。
下面是我正在做的一个简单示例:
class foo(object):
def read_files_in_dir(...)
....
def filter_x(...):
for file in read_files_in_dir(...):
if file.startswith("x"):
yield file
def filter_y(....):
for file in read_files_in_dir(...):
if file.startswith("y"):
yield file
...
我不想把所有的filter
函数的结果合并在一起,因为每个结果的意义不同,因为我在读取不同的目录,而这些目录需要不同的过滤方式。
有没有办法可以有一个中心函数来处理循环,同时又能提供不同的过滤选项,而不需要把参数搞得复杂得不可思议?
// 编辑
现在我这样做:
class Something(object):
@staticmethod
def read_files_in_dir(self, directory, filter_func=lambda _: return True):
for file in directory:
if filter_func(file):
yield file
class Filters(object):
@staticmethod
def filter1(file):
return True if *some_condition* else False
然后我运行类似这样的代码:
filtered = Something.read_files_in_dir(*directory*, Something.Filters.filter1)
有没有什么改进的建议?
4 个回答
Dologan的回答很好。 他的意思是把过滤器的值当作参数传给过滤函数。 不过,为了让过滤器更强大,我会使用一个过滤字典。 在这个字典里,你可以指定搜索的类型和对应的值: 比如说: filterList = {'start':'y',.....)
如果你想更高级一点,可以把过滤函数放在一个列表里,然后把字符串作为参数传进去。 比如说:
filename = 'try_me.py'
filterString = 't'
filterListA = [str.startswith]
filterListB = [str.endswith, str.startswith]
filterListC = [str.find]
def my filter(filterList, filterString):
for filterFunc in filterList:
print filterFunc(filename,filterString)
在构建一个过滤系统时,通常的思路是先创建一个数据集合,然后把这个集合里的每个项目都通过一系列的过滤函数来处理。每个过滤函数会接收一个项目,并返回一个布尔值(也就是“真”或“假”)。只有当所有的过滤器都返回“真”的时候,这个项目才会被保留下来。
下面是一个简单的例子,采用了函数式编程的风格。如果需要的话,也可以很容易地转换成面向对象的方式来使用:
def main():
universe = read_files_in_dir()
filters = [is_odd, larger_than_ten]
for item in universe:
if all(f(item) for f in filters):
print item
def read_files_in_dir():
return list(range(20))
def is_odd(item):
return bool(item % 2)
def larger_than_ten(item):
return item > 10
main()
在编程中,有时候我们会遇到一些问题,尤其是在使用某些工具或库的时候。这些问题可能会让我们感到困惑,尤其是当我们刚开始学习编程的时候。比如,有人可能会在使用某个特定的功能时,发现它没有按照预期工作。这种情况很常见,尤其是当我们对这个工具还不够熟悉的时候。
在这种情况下,查看网上的讨论,比如StackOverflow上的帖子,通常能找到一些解决方案或者其他人的经验分享。很多时候,其他开发者会遇到类似的问题,他们会在网上寻求帮助,或者分享他们的解决办法。这些讨论可以帮助我们更好地理解问题的根源,以及如何解决它。
总之,遇到问题时,不要气馁,网上有很多资源和社区可以帮助你。记得多多查阅相关的讨论和解决方案,这样你会逐渐掌握更多的知识和技能。
predicates = [
lambda x: x % 3 == 0,
lambda x: x % 5 == 0
]
items = range(0, 100)
filtered = [
item for item in items if
all(predicate(item) for predicate in predicates)
]
print(filtered)
你的例子可能有点过于简单,不过下面的代码应该能做到和你的差不多的效果:
def read_files_in_dir(...)
...
def filter(self, param, ...):
return (file for file in read_files_in_dir(...) if file.startswith(param))
如果你的过滤条件比一个测试能处理的要复杂,你可以创建更多的方法或函数,把文件实例传给它们,然后根据你需要的标准返回真或假。