Tom*_*Tom 12 python functional-programming
我有两个类似的代码需要解析,我不确定实现这个的最pythonic方式.
假设我有两个相似的"代码"
secret_code_1 = 'asdf|qwer-sdfg-wert$$otherthing'
secret_code_2 = 'qwersdfg-qw|er$$otherthing'
Run Code Online (Sandbox Code Playgroud)
两个代码以...结尾$$otherthing并包含多个值-
起初我想过functools.wrap将一些常用逻辑与特定于每种类型代码的逻辑分开,如下所示:
from functools import wraps
def parse_secret(f):
@wraps(f)
def wrapper(code, *args):
_code = code.split('$$')[0]
return f(code, *_code.split('-'))
return wrapper
@parse_secret
def parse_code_1b(code, a, b, c):
a = a.split('|')[0]
return (a,b,c)
@parse_secret
def parse_code_2b(code, a, b):
b = b.split('|')[1]
return (a,b)
Run Code Online (Sandbox Code Playgroud)
但是这样做会让你有点混淆你应该实际传递给parse_code_*函数的参数,即
parse_code_1b(secret_code_1)
parse_code_2b(secret_code_2)
Run Code Online (Sandbox Code Playgroud)
因此,为了更容易理解函数的形式参数,我将逻辑更改为:
def _parse_secret(parse_func, code):
_code = code.split('$$')[0]
return parse_func(code, *_code.split('-'))
def _parse_code_1(code, a, b, c):
"""
a, b, and c are descriptive parameters that explain
the different components in the secret code
returns a tuple of the decoded parts
"""
a = a.split('|')[0]
return (a,b,c)
def _parse_code_2(code, a, b):
"""
a and b are descriptive parameters that explain
the different components in the secret code
returns a tuple of the decoded parts
"""
b = b.split('|')[1]
return (a,b)
def parse_code_1(code):
return _parse_secret(_parse_code_1, code)
def parse_code_2(code):
return _parse_secret(_parse_code_2, code)
Run Code Online (Sandbox Code Playgroud)
现在,更容易推断你传递给函数的内容:
parse_code_1(secret_code_1)
parse_code_2(secret_code_2)
Run Code Online (Sandbox Code Playgroud)
但是这段代码更加冗长.
有一个更好的方法吗?面向对象的方法在这里会更有意义吗?
函数式方法更加简洁并且更有意义。
我们可以从用纯函数表达概念开始,这是最容易组合的形式。
剥离$$otherthing和分割值:
parse_secret = lambda code: code.split('$$')[0].split('-')
Run Code Online (Sandbox Code Playgroud)
取内部值之一:
take = lambda value, index: value.split('|')[index]
Run Code Online (Sandbox Code Playgroud)
将其中一个值替换为其内部值:
parse_code = lambda values, p, q: \
[take(v, q) if p == i else v for (i, v) in enumerate(values)]
Run Code Online (Sandbox Code Playgroud)
这两种类型的代码有 3 个区别:
我们可以通过描述这些差异来编写解析函数。分割值保持打包状态,以便更容易组合。
compose = lambda length, p, q: \
lambda code: parse_code(parse_secret(code)[:length], p, q)
parse_code_1 = compose(3, 0, 0)
parse_code_2 = compose(2, 1, 1)
Run Code Online (Sandbox Code Playgroud)
并使用组合函数:
secret_code_1 = 'asdf|qwer-sdfg-wert$$otherthing'
secret_code_2 = 'qwersdfg-qw|er$$otherthing'
results = [parse_code_1(secret_code_1), parse_code_2(secret_code_2)]
print(results)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
406 次 |
| 最近记录: |