在Python 3中,您可以创建如下类:
class foo:
def __init__(self, x):
self.x=x
def __call__(self, y):
self.x = self.x + 1
return (self.x, y)
然后可以将它用作具有如下状态的仿函数:
functor = foo(5)
x = 44354234
print('(1.1) ', functor(7))
print('(1.2) ', functor(8))
print('(1.2) ', functor(9))
在实践中,我创建了一个返回函数的函数。但是,第一个函数实际上是一个返回可调用对象的构造函数。恕我直言通过允许开发人员扩展类,添加方法等等来打开一堆蠕虫。此外,__init__
中的代码自然会先于__call__
中的代码,因为它需要执行,并且在类构造中并不清楚。最后,Python 3'方式'建议在类上使用函数。
由于这个原因,我创建了一个类似的函数版本,它具有较少的样板代码和恕我直言的读取更自然:
def bar(x):
def f(y):
nonlocal x
x = x + 1
return (x,y)
return f
functor2 = bar(5)
x = 345234234
print('(2.1) ', functor2(7))
print('(2.2) ', functor2(8))
print('(2.3) ', functor2(9))
然而,它使用nonlocal
并且由于我没有想到的原因可能不直观。第二种方法是良好的做法,还是有危险的窖藏?哪个应该是Python 3的首选?特别是因为我对nonlocal
的使用经验很少。
答案 0 :(得分:1)
近年来,Python开发策略看起来像是“让我们在Python中融入其他语言的每个功能”,这样就能够以各种方式完成单个任务。
因此,做某些事情真的没有“首选方式”,这完全取决于开发人员想要做什么。因此,在某些情况下可能需要使用Class
来创建有状态函数并允许扩展它。使用nonlocal
闭包是更常见的IMO,并且没有任何不直观的内容。另一个问题是,当将这种方法用于方法装饰器时,那么使用函数就必须编写更少的代码,而对于类,由于self
,你必须添加更多“魔法”。
P.S。在Python中,函数可以具有属性,因此使用x
作为f
内部函数的属性而不是nonlocal
的另一种方法是使用def bar(x):
def f(y):
f.x=f.x+1
return (f.x, y)
f.x=x
return f
,尽管它不那么常见你。
SELECT
projects_tasks.id AS task_id,
projects_tasks.name AS task_name,
projects_tasks.created_by AS task_creator,
labels.name AS task_label,
users.name AS task_responsible_name,
users.surname AS task_responsible_surname,
users2.name AS task_assigner_name,
users2.surname AS task_assigner_surname,
(CASE WHEN projects_tasks_deadlines.deadline_active = '1' THEN projects_tasks_deadlines.deadline ELSE projects_tasks.deadline END) AS task_deadline
FROM projects_tasks
INNER JOIN `labels` ON labels.id = projects_tasks.label_id
INNER JOIN `users` ON users.id = projects_tasks.responsible_id
INNER JOIN `users` AS `users2` ON users2.id = projects_tasks.created_by
LEFT JOIN projects_tasks_deadlines ON projects_tasks_deadlines.task_id = projects_tasks.id
WHERE projects_tasks.project_id = '1'
AND labels.id != '8'
GROUP BY projects_tasks.id
ORDER BY CASE WHEN projects_tasks_deadlines.deadline_active = '1' THEN -projects_tasks_deadlines.deadline ELSE -projects_tasks.deadline END DESC
编辑:为返回语句添加了额外的缩进