Понимание функций первого класса - PullRequest
0 голосов
/ 20 октября 2019

Я пытаюсь понять первоклассные функции и то, как их можно использовать в практическом примере. В качестве примера я привел аутентификацию перед вызовом определенных функций для вошедшего в систему пользователя. Например:

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'

Это правильное понимание функций первого класса? Вышесказанное больше похоже на концепцию wrapper или decorator. Это в основном одно и то же, или в чем разница между этими тремя понятиями?

1 Ответ

2 голосов
/ 20 октября 2019

Первый класс просто означает, что он может существовать сам по себе. Его не нужно сопровождать никого.

Методы

Где в таких языках, как 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)

fuzz

имя сообщение

fuzz


Примечание 1. Типы данных также относятся к первоклассным гражданам во всех приведенных здесь примерах. string сам по себе в Java. Поскольку 'a name' - это тоже str в Python. Таким образом, к первому классу применимы не только функции и классы.

Примечание 2. Также в случае с классом у вас могут быть методы, которые не действуют на self илиthis, они упоминаются как статические методы. По сути, функция в классе.

Доп. Функции

Об этом есть фантастическая сатира, которую вы можете прочитать в какой-то момент.

Казнь в «Королевстве существительных» Стива Йегге

Дэвид Бизли, совсем недавно на PyCon 2019, выступил с выдающейся лекцией по этой теме, которая довольно блестяще демонстрирует силу функции.

Лямбда-исчисление с нуля

...