>  기사  >  백엔드 개발  >  Python의 내장 함수가 전부가 아닌 이유를 이해하시나요?

Python의 내장 함수가 전부가 아닌 이유를 이해하시나요?

coldplay.xixi
coldplay.xixi앞으로
2020-10-21 17:12:461681검색

python 동영상 튜토리얼 칼럼에서는 Python 내장 함수를 소개합니다.

Python의 내장 함수가 전부가 아닌 이유를 이해하시나요?

이전 글 Python Cat에서는 목록을 생성하는 두 가지 방법, 즉 리터럴 사용법[]과 내장형 사용법 list()를 비교한 후 분석해 보았습니다. 그들의 달리기 속도. Python猫的上一篇文章中,我们对比了两种创建列表的方法,即字面量用法 [] 与内置类型用法 list(),进而分析出它们在运行速度上的差异。

在分析为什么 list() 会更慢的时候,文中说到它需要经过名称查找与函数调用两个步骤,那么,这就引出了一个新的问题:list() 不是内置类型么,为什么它不能直接就调用创建列表的逻辑呢?也就是说,为什么解释器必须经过名称查找,才能“认识”到该做什么呢?

其实原因很简单:内置函数/内置类型的名称并不是关键字,它们只是解释器内置的一种便捷功能,方便开发者开箱即用而已。

PS:内置函数 built-in function 和内置类型 built-in type 很相似,但 list() 实际是一种内置类型而不是内置函数。我曾对这两种易混淆的概念做过辨析,请查看这篇文章。为了方便理解与表述,以下统称为内置函数。

1、内置函数的查找优先级最低

内置函数的名称并不属于关键字,它们是可以被重新赋值的。

比如下面这个例子:

# 正常调用内置函数list(range(3))  # 结果:[0, 1, 2]# 定义任意函数,然后赋值给 listdef test(n):
    print("Hello World!")
list = test
list(range(3)) # 结果:Hello World!复制代码

Python의 내장 함수가 전부가 아닌 이유를 이해하시나요?

在这个例子中,我们将自定义的 test 赋值给了 list,程序并没有报错。这个例子甚至还可以改成直接定义新的同名函数,即"def list(): …"。

这说明了 list 并不是 Python 限定的关键字/保留字。

查看官方文档,可以发现 Python 3.9 有 35 个关键字,明细如下:

Python의 내장 함수가 전부가 아닌 이유를 이해하시나요?

如果我们将上例的 test 赋值给任意一个关键字,例如"pass=test",就会报错:SyntaxError: invalid syntax。

由此,我们可以从这个角度看出内置函数并不是万能的:它们的名称并不像关键字那般稳固不变,虽然它们处在系统内置作用域里,但是却可以被用户局部作用域的对象所轻松拦截掉!

因为解释器查找名称的顺序是“局部作用域->全局作用域->内置作用域”,因此内置函数其实是处在最低优先级。

对于新手来说,这有一定的可能会发生意想不到的情况(内置函数有 69 个,要全记住是有难度的)。

那么,为什么 Python 不把所有内置函数的名称都设为不可复写的关键字呢?

一方面原因是它想控制关键字的数量,另一方面可能是想留给用户更多的自由。内置函数只是解释器的推荐实现而已,开发者可以根据需要,实现出与内置函数同名的函数。

不过,这样的场景极少,而且开发者一般会定义成不同名的函数,以 Python 标准库为例,ast模块有 literal_eval() 函数(对标 eval() 内置函数)、pprint 模块有 pprint() 函数(对标 print() 内置函数)、以及itertools

list()가 느린 이유를 분석할 때 기사에서는 이름 검색과 함수 호출이라는 두 단계를 거쳐야 한다고 언급했습니다. 그러면 새로운 질문이 생깁니다.

list()는 내장 유형이 아닙니다. 왜 목록 생성 로직을 직접 호출할 수 없나요? 즉, 통역사가 무엇을 해야 할지 "알기" 위해 이름 조회를 거쳐야 하는 이유는 무엇입니까?

사실 그 이유는 매우 간단합니다. 내장 함수/내장 유형의 이름은 키워드가 아니라 개발자가 즉시 사용할 수 있도록 인터프리터에 내장된 편리한 함수일 뿐입니다.

Python의 내장 함수가 전부가 아닌 이유를 이해하시나요?PS: 내장 함수는 내장 유형과 매우 유사하지만 list()는 실제로 내장 함수가 아닌 내장 유형입니다. 나는 이 두 가지 혼란스러운 개념에 대해 몇 가지 분석을 수행했습니다. 이 기사를 확인하십시오. 이하에서는 이해와 표현을 용이하게 하기 위해 내장기능이라 통칭합니다.

1. 내장 함수의 검색 우선순위가 가장 낮습니다

내장 함수의 이름은 키워드가 아니며 재지정될 수 있습니다.

예: rrreee

Python의 내장 함수가 전부가 아닌 이유를 이해하시나요?

Python의 내장 함수가 전부가 아닌 이유를 이해하시나요?이 예에서는 사용자 정의 테스트를 목록에 할당했지만 프로그램은 오류를 보고하지 않았습니다. 이 예는 동일한 이름의 새 함수, 즉 "def list(): ..."를 직접 정의하도록 변경될 수도 있습니다.

이것은 list가 Python에서 제한된 키워드/예약어가 아님을 보여줍니다.

🎜공식 문서를 보면 Python 3.9에는 35개의 키워드가 있는 것을 확인할 수 있으며, 세부 내용은 다음과 같습니다. 🎜🎜Python의 내장 함수가 전부가 아닌 이유를 이해하시나요?🎜🎜위 예의 테스트를 "pass=test"와 같은 임의의 키워드에 할당하면 , 오류가 보고됩니다: SyntaxError:잘못된 구문. 🎜🎜따라서 우리는 내장 기능이 전능하지 않다는 것을 알 수 있습니다. 🎜그 이름은 시스템의 내장 범위에 있지만 사용자가 로컬에서 사용할 수 있는 키워드만큼 안정적이지 않습니다. . 범위 개체를 쉽게 가로챌 수 있습니다! 🎜🎜🎜통역사가 이름을 찾는 순서는 "로컬 범위 -> 전역 범위 -> 내장 범위"이므로 실제로 내장 함수의 우선순위가 가장 낮습니다. 🎜🎜초보자의 경우 예상치 못한 상황이 발생할 수 있습니다. (69개의 내장된 기능이 있어 다 기억하기 어렵습니다.) 🎜🎜그래서, 🎜왜 Python은 모든 내장 함수의 이름을 재정의할 수 없는 키워드로 만들지 않습니까? 🎜🎜🎜한편으로는 키워드 수를 제어하고 다른 한편으로는 사용자에게 더 많은 자유를 주고 싶을 수도 있습니다. 내장 함수는 인터프리터의 권장 구현일 뿐입니다. 개발자는 필요에 따라 내장 함수와 동일한 이름을 가진 함수를 구현할 수 있습니다. 🎜🎜그러나 이러한 시나리오는 드물며 개발자는 일반적으로 Python 표준 라이브러리를 예로 들어 함수를 정의합니다. ast 모듈에는 literal_eval() 함수(내장 eval( ) 함수), pprint 모듈에는 pprint() 함수가 있고(print() 내장 함수와 비교) itertools 모듈에는 zip_longest() 함수가 있습니다. (zip() 내장 함수와 비교)...🎜🎜2. 내장 함수가 가장 빠르지 않을 수 있습니다🎜🎜 내장 함수의 이름은 예약어가 아니며, 이름 검색 마지막 순서에서는 내장 기능이 가장 빠르지 않을 수 있습니다. 🎜🎜🎜🎜🎜이전 기사에서는 []가 list()보다 2~3배 빠르다는 사실을 보여주었습니다. 실제로 이는 str(), tuple(), set()과 같은 내장 유형으로도 확장될 수 있습니다. ), dict() 등 모든 리터럴 사용은 내장 유형 사용보다 약간 빠릅니다. 🎜🎜이러한 내장 유형의 경우 xxx()를 호출하면 클래스가 인스턴스화된다는 것을 간단히 이해할 수 있습니다. 객체 지향 언어에서는 클래스가 먼저 인스턴스화되고 사용되는 것이 일반적입니다. 🎜🎜그러나 이 접근 방식은 때때로 번거로워 보일 수 있습니다. 🎜사용의 용이성을 위해 Python은 문자열, 목록, 튜플 및 사전과 같은 데이터 유형을 나타내는 일반적으로 사용되는 일부 내장 유형, 즉 "", [], (), {} 등에 대한 리터럴 표현을 제공합니다. 🎜🎜🎜🎜🎜🎜문서 출처: docs.python.org/3/reference…🎜

일반적으로 모든 프로그래밍 언어에는 리터럴 표현이 있어야 하지만 기본적으로 숫자 유형, 문자열, 부울 유형 및 null과 같은 기본 유형으로 제한됩니다.

Python은 여러 데이터 구조 유형에 대한 리터럴도 추가하여 더 편리합니다. 이는 내장 기능이 가장 빠르지 않은 이유도 설명합니다.

일반적으로 말하면, 내장 함수는 동일한 완전한 함수를 사용하여 항상 사용자 정의 함수보다 빠릅니다. 왜냐하면 인터프리터가 len()과 같은 일부 기본 최적화를 수행할 수 있기 때문입니다. 내장 함수는 사용자 정의 x보다 확실히 빠릅니다. .len() 이 기능은 빠릅니다.

이를 바탕으로 "내장 기능이 항상 빠르다"는 오해를 형성하는 사람들도 있습니다.

사용자 정의 함수에 비해 통역사의 내장 기능은 백도어에 가깝지만 리터럴 표현은 내장 함수에 비해 백도어가 더 빠릅니다.

즉, 일부 내장 함수/내장 유형은 리터럴 표현이 있을 때 가장 빠르지 않습니다!

요약

파이썬 자체가 전능하지 않고 문법적 구성 요소(내장 함수/유형)도 전능하지 않다는 것은 사실입니다. 그러나 일반적으로 우리는 내장된 함수/유형이 항상 "우수"하고, 많은 특별 우대를 받으며, "전능한" 것처럼 보인다고 생각합니다.

이 글은 "list()가 실제로 []에게 진다"는 문제를 해결하고 실제로 내장 함수에 몇 가지 단점이 있음을 두 가지 관점에서 드러냅니다. 내장 함수의 이름은 키워드가 아니며, 내장 범위는 우선 순위가 가장 낮은 이름 검색에 위치하므로 일부 내장 함수/유형은 호출 시 해당 리터럴 표현보다 훨씬 느리게 실행됩니다.

이 기사는 이전 주제인 "왜 Python"에 대한 토론을 확장하는 동시에 이전 내용을 풍부하게 하는 동시에 모든 사람이 Python의 몇 가지 기본 개념과 구현을 이해하는 데도 도움이 됩니다.

이 글이 마음에 드셨다면 좋아요와 응원 부탁드립니다! 또한, 비슷한 주제를 20개 이상 작성했습니다. Python猫를 따라 확인하고 Github에서 작은 별표를 눌러주세요~~

관련 무료 학습 권장 사항: python 비디오 튜토리얼

위 내용은 Python의 내장 함수가 전부가 아닌 이유를 이해하시나요?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 juejin.im에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제