【问题标题】:Understanding first class functions了解一流的功能
【发布时间】:2020-02-16 11:33:19
【问题描述】:

我正在尝试了解一流的功能以及如何在实际示例中使用它们。我想出的示例是在为登录用户调用特定函数之前进行身份验证。例如:

def authenticate(user_id):
    if user_id != 1: return None
    def call_func(func_name):
        print(f"{user_id} is logged in! ==> Calling function '{func_name}'")
    return call_func

user0 = authenticate(user_id=0)
if user0: user0(func_name='xyz')
user1 = authenticate(user_id=1)
if user1: user1(func_name='xyz')

哪些打印:

1 已登录! ==> 调用函数'xyz'

这是对一等函数的正确理解吗?以上似乎更像是wrapperdecorator 的概念。这些基本上是一样的吗,或者这三个概念有什么区别?

【问题讨论】:

  • 我认为您的理解可能存在类别错误。 “一流的功能”不是一种技术;这是对您使用的语言中的函数是一流的事实的描述。您可以用来利用这一事实的技术之一是包装和/或装饰。还有其他的。
  • "first class" 只是意味着函数本身就是可以传递、存储在变量等中的对象。与函数不是对象的 C 相比。如果你想传递一个函数,你能做的最好的就是传递一个指向函数的指针。
  • 我认为这对于 Stack Overflow 来说太宽泛了——你可以在网上找到很多关于“一流函数”概念的定义。装饰器是一个基于此的概念——装饰器是一个函数,其输入和输出都是函数,如果没有一流的函数,你就无法做到这一点。但是装饰器只是通过一流的功能实现的几种功能之一。
  • 您正在考虑的涉及传递函数的概念称为“高阶函数”。

标签: python decorator wrapper


【解决方案1】:

头等舱只是意味着它可以独立存在。不需要任何人陪同。

方法

在 Java 和 C# 等语言中,您可以创建类以将 方法 塞入其中。

class Logger {
    public Logger(string name) {
        this.name = name;
    }

    public void Log(string msg) {
        System.out.print(name + msg);
    }
}

然后您使用这些类的实例来调用方法。

Logger logger = new Logger("a name");
logger.Log("a message");

函数只能作为类的方法存在。类是一等公民。

功能

在像 python 这样的语言中,你可以只拥有一个函数。

def log(name, msg):
    print(name, msg)

然后调用那个函数。

log('a name', 'a message')

函数可以简单地存在。

Python 笔记

Python 有很好的类。所以如果你仍然想避免一直输入'a name',你可以使用它们。

class Logger:
    def __init__(self, name):
        self.name = name

    def log(self, msg):
        print(self.name, msg)

logger = Logger('a name')
logger.log('a message')

由于函数是一等公民,闭包也是一回事,同样可以通过函数来​​实现。

def logger(name):
    def log(msg):
        print(name, msg)
    return log

log = logger('a name')
log('a message')

装饰器

装饰器只是利用其他函数的简单函数。以前面的log函数为例。如果我们有一个fuzz 装饰器,并用它来装饰log 函数,它本质上就是用自己的日志函数替换了我们的日志函数(恰好调用了我们的函数)。

def fuzz(func):
    def fuzzed_func(*args, **kwargs):
        print('fuzz')
        func(*args, **kwargs)
        print('fuzz')
    return fuzzed_func

@fuzz
def log(name, msg):
    print(name, msg)

模糊

一个名字一个消息

模糊


注意 1. 在这里给出的所有示例中,数据类型也是一等公民。 string 本身就在 Java 中。因为'a name' 本身也是str,在Python 中也是如此。所以,不仅函数和类适用于第一类。

注意 2. 还要考虑在类的情况下,您可以有不作用于 selfthis 的方法,它们被引用为静态方法。本质上是类中的一个函数。

附加功能

关于这一点有一篇精彩的讽刺文章,您可能想在某个时候阅读。

Execution in the Kingdom of Nouns by Steve Yegge

最近在 PyCon 2019 上,David Beazley 就该主题发表了出色的演讲,非常出色地展示了函数的强大功能。

Lambda Calculus from the Ground Up

【讨论】:

    猜你喜欢
    • 2015-08-06
    • 2011-04-21
    • 2015-04-17
    • 1970-01-01
    • 1970-01-01
    • 2012-06-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多