목차
1. 단일 선행 밑줄: _var
2. 단일 끝 밑줄 var_
3. 이중 선행 밑줄 __var
4.双前导和双末尾下划线 _var_
5.单下划线 _
백엔드 개발 파이썬 튜토리얼 Python에서 밑줄의 의미와 용도는 무엇입니까?

Python에서 밑줄의 의미와 용도는 무엇입니까?

Apr 20, 2023 pm 08:04 PM
python

1. 단일 선행 밑줄: _var

변수 및 메서드 이름과 관련하여 단일 밑줄 접두사는 일반적인 의미를 갖습니다. 이는 프로그래머에게 상기시켜주는 것입니다. 즉, Python 커뮤니티는 이것이 의미하는 바에 동의하지만 프로그램의 동작은 영향을 받지 않는다는 의미입니다.

밑줄 접두사의 의미는 단일 밑줄로 시작하는 변수나 메소드는 내부 전용임을 다른 프로그래머에게 알리는 것입니다. 이 규칙은 PEP 8에 정의되어 있습니다.

이것은 Python에서 필수 사항이 아닙니다. Python에는 Java처럼 "개인" 변수와 "공용" 변수를 크게 구분하지 않습니다. 이는 마치 누군가가 다음과 같이 작은 밑줄 경고 표시를 붙인 것과 같습니다.

"이것은 실제로 클래스의 공개 인터페이스의 일부가 아닙니다. 그냥 그대로 두세요."

2. 단일 끝 밑줄 var_

때로는 변수에 가장 적합한 이름이 이미 키워드에 의해 사용되는 경우도 있습니다. 따라서 Python에서는 class 또는 def와 같은 이름을 변수 이름으로 사용할 수 없습니다. 이 경우 밑줄을 추가하여 이름 지정 충돌을 해결할 수 있습니다:

>>> def make_object(name, class):
SyntaxError: "invalid syntax"

>>> def make_object(name, class_):
...    pass
로그인 후 복사

간단히 말해서, 단일 후행 밑줄(접미사)은 Python 키워드와의 이름 지정 충돌을 피하기 위한 규칙입니다. PEP 8은 이 규칙을 설명합니다.

3. 이중 선행 밑줄 __var

지금까지 다룬 모든 명명 패턴의 의미는 합의된 규칙에서 비롯됩니다. 이중 밑줄로 시작하는 Python 클래스 속성(변수 및 메서드 포함)의 경우 상황이 약간 다릅니다.

이중 밑줄 접두어를 사용하면 Python 인터프리터가 속성 이름을 다시 작성하여 하위 클래스의 이름 충돌을 방지합니다.

이것을 이름 맹글링(name mangling)이라고도 합니다. 통역사는 클래스가 확장될 때 충돌할 가능성을 줄이기 위해 변수의 이름을 변경합니다.

이 말이 추상적으로 들리는 걸 압니다. 그래서 설명을 위해 작은 코드 예제를 만들었습니다.

class Test:
   def __init__(self):
       self.foo = 11
       self._bar = 23
       self.__baz = 23
로그인 후 복사

내장된 dir() 함수를 사용하여 이 개체의 속성을 살펴보겠습니다.

>>> t = Test()
>>> dir(t)
['_Test__baz', '__class__', '__delattr__', '__dict__', '__dir__',
'__doc__', '__eq__', '__format__', '__ge__', '__getattribute__',
'__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__',
'__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
'__setattr__', '__sizeof__', '__str__', '__subclasshook__',
'__weakref__', '_bar', 'foo']
로그인 후 복사

위는 이 개체의 속성 목록입니다. 이 목록을 살펴보고 원래 변수 이름인 foo, _bar 및 __baz를 찾아보겠습니다. 몇 가지 흥미로운 변경 사항을 발견할 수 있을 것입니다. foo,_bar__baz - 我保证你会注意到一些有趣的变化。

self.foo变量在属性列表中显示为未修改为foo。self._bar的行为方式相同 - 它以_bar的形式显示在类上。 就像我之前说过的,在这种情况下,前导下划线仅仅是一个约定。 给程序员一个提示而已。然而,对于self.__baz而言,情况看起来有点不同。 当你在该列表中搜索__baz时,你会看不到有这个名字的变量。

__baz出什么情况了?

如果你仔细观察,你会看到此对象上有一个名为_Test__baz的属性。 这就是Python解释器所做的名称修饰。 它这样做是为了防止变量在子类中被重写。

让我们创建另一个扩展Test类的类,并尝试重写构造函数中添加的现有属性:

class ExtendedTest(Test):
   def __init__(self):
       super().__init__()
       self.foo = 'overridden'
       self._bar = 'overridden'
       self.__baz = 'overridden'
로그인 후 복사

现在,你认为foo,_bar__baz的值会出现在这个ExtendedTest类的实例上吗? 我们来看一看:

>>> t2 = ExtendedTest()
>>> t2.foo
'overridden'
>>> t2._bar
'overridden'
>>> t2.__baz
AttributeError: "'ExtendedTest' object has no attribute '__baz'"
로그인 후 복사

等一下,当我们尝试查看t2 .__ baz的值时,为什么我们会得到AttributeError? 名称修饰被再次触发了! 事实证明,这个对象甚至没有__baz属性:

>>> dir(t2)
['_ExtendedTest__baz', '_Test__baz', '__class__', '__delattr__',
'__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__',
'__getattribute__', '__gt__', '__hash__', '__init__', '__le__',
'__lt__', '__module__', '__ne__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__',
'__subclasshook__', '__weakref__', '_bar', 'foo', 'get_vars']
로그인 후 복사

正如你可以看到__baz变成_ExtendedTest__baz以防止意外修改:

>>> t2._ExtendedTest__baz
'overridden'
로그인 후 복사

但原来的_Test__baz还在:

>>> t2._Test__baz
42
로그인 후 복사

双下划线名称修饰对程序员是完全透明的。 下面的例子证实了这一点:

class ManglingTest:
   def __init__(self):
       self.__mangled = 'hello'

   def get_mangled(self):
       return self.__mangled

>>> ManglingTest().get_mangled()
'hello'
>>> ManglingTest().__mangled
AttributeError: "'ManglingTest' object has no attribute '__mangled'"
로그인 후 복사

名称修饰是否也适用于方法名称? 是的,也适用。名称修饰会影响在一个类的上下文中,以两个下划线字符("dunders")开头的所有名称:

class MangledMethod:
   def __method(self):
       return 42

   def call_it(self):
       return self.__method()

>>> MangledMethod().__method()
AttributeError: "'MangledMethod' object has no attribute '__method'"
>>> MangledMethod().call_it()
42
로그인 후 복사

这是另一个也许令人惊讶的运用名称修饰的例子:

_MangledGlobal__mangled = 23

class MangledGlobal:
   def test(self):
       return __mangled

>>> MangledGlobal().test()
23
로그인 후 복사

在这个例子中,我声明了一个名为_MangledGlobal__mangled的全局变量。然后我在名为MangledGlobal的类的上下文中访问变量。由于名称修饰,我能够在类的test()方法内,以__mangled来引用_MangledGlobal__mangled全局变量。

Python解释器自动将名称__mangled扩展为_MangledGlobal__mangled

self.foo 변수는 속성 목록에서 수정되지 않은 foo로 표시됩니다. self._bar는 동일한 방식으로 동작합니다. 즉, 클래스에 _bar로 표시됩니다. 앞서 말했듯이 이 경우 선행 밑줄은 단지 관례일 뿐입니다. 프로그래머를 위한 힌트입니다. 그러나 self.__baz의 경우 상황이 약간 달라 보입니다. 이 목록에서 __baz를 검색하면 이 이름을 가진 변수가 표시되지 않습니다.

__baz에게 무슨 일이 일어났나요?

자세히 살펴보면 이 개체에 _Test__baz라는 속성이 있는 것을 볼 수 있습니다. 이는 Python 인터프리터가 수행하는 이름 맹글링입니다. 이는 하위 클래스에서 변수가 재정의되는 것을 방지하기 위해 수행됩니다.

Test 클래스를 확장하는 또 다른 클래스를 만들고 생성자에 추가된 기존 속성을 재정의해 보겠습니다. 🎜
class PrefixPostfixTest:
   def __init__(self):
       self.__bam__ = 42

>>> PrefixPostfixTest().__bam__
42
로그인 후 복사
로그인 후 복사
🎜이제 foo, _bar__baz를 생각해보세요. 코드 값>이 ExtendedTest 클래스의 인스턴스에 표시됩니까? 살펴보겠습니다: 🎜
>>> for _ in range(32):
...    print('Hello, World.')
로그인 후 복사
로그인 후 복사
🎜잠깐만, t2.__baz의 값을 보려고 할 때 왜 AttributeError가 발생합니까? 이름 수정이 다시 시작되었습니다! 이 객체에는 __baz 속성도 없는 것으로 나타났습니다. 🎜
>>> car = ('red', 'auto', 12, 3812.4)
>>> color, _, _, mileage = car

>>> color
'red'
>>> mileage
3812.4
>>> _
12
로그인 후 복사
로그인 후 복사
🎜 보시다시피 __baz는 실수로 인한 수정을 방지하기 위해 _ExtendedTest__baz가 됩니다. : 🎜
>>> 20 + 3
23
>>> _
23
>>> print(_)
23

>>> list()
[]
>>> _.append(1)
>>> _.append(2)
>>> _.append(3)
>>> _
[1, 2, 3]
로그인 후 복사
로그인 후 복사
🎜하지만 원본 _Test__baz는 여전히 존재합니다. 🎜rrreee🎜이중 밑줄 이름 장식은 프로그래머에게 완전히 투명합니다. 다음 예는 이를 확인합니다. 🎜rrreee🎜이름 장식이 메소드 이름에도 적용됩니까? 예, 그것도 적용됩니다. 이름 장식은 클래스 컨텍스트에서 두 개의 밑줄 문자 ("dunders")로 시작하는 모든 이름에 영향을 미칩니다. 🎜rrreee🎜 이것은 이름 장식 사용에 대한 또 다른 아마도 놀라운 예입니다. 🎜rrreee 🎜이 예에서는 _MangledGlobal__mangled라는 전역 변수를 선언했습니다. 그런 다음 MangledGlobal이라는 클래스의 컨텍스트에서 변수에 액세스합니다. 맹글링이라는 이름 때문에 클래스의 test() 메서드 내에서 _MangledGlobal__mangled 전역 변수를 __mangled로 참조할 수 있습니다. 🎜🎜Python 인터프리터는 두 개의 밑줄 문자로 시작하므로 __mangled라는 이름을 _MangledGlobal__mangled로 자동 확장합니다. 이는 이름 장식이 클래스 속성과 특별히 연관되어 있지 않음을 나타냅니다. 클래스 컨텍스트에서 사용되는 두 개의 밑줄 문자로 시작하는 모든 이름에 작동합니다. 🎜🎜흡수할 것이 많습니다. 🎜🎜솔직히 이런 예시와 설명이 그냥 머리에서 튀어나온 게 아니었습니다. 그것을 생각해 내기 위해서는 약간의 연구와 처리가 필요했습니다. 나는 항상 Python을 사용해왔고 수년 동안 사용해왔지만 이와 같은 규칙과 특별한 경우가 항상 마음에 떠오르는 것은 아닙니다. 🎜🎜때때로 프로그래머에게 가장 중요한 기술은 "패턴 인식"과 정보를 찾을 위치를 아는 것입니다. 이 시점에서 약간의 압도감을 ​​느끼더라도 걱정하지 마십시오. 시간을 내어 이 기사의 몇 가지 예를 시도해 보십시오. 🎜

让这些概念完全沉浸下来,以便你能够理解名称修饰的总体思路,以及我向您展示的一些其他的行为。如果有一天你和它们不期而遇,你会知道在文档中按什么来查。

4.双前导和双末尾下划线 _var_

也许令人惊讶的是,如果一个名字同时以双下划线开始和结束,则不会应用名称修饰。 由双下划线前缀和后缀包围的变量不会被Python解释器修改:

class PrefixPostfixTest:
   def __init__(self):
       self.__bam__ = 42

>>> PrefixPostfixTest().__bam__
42
로그인 후 복사
로그인 후 복사

但是,Python保留了有双前导和双末尾下划线的名称,用于特殊用途。 这样的例子有,__init__对象构造函数,或__call__ — 它使得一个对象可以被调用。

这些dunder方法通常被称为神奇方法 - 但Python社区中的许多人(包括我自己)都不喜欢这种方法。

最好避免在自己的程序中使用以双下划线(“dunders”)开头和结尾的名称,以避免与将来Python语言的变化产生冲突。

5.单下划线 _

按照习惯,有时候单个独立下划线是用作一个名字,来表示某个变量是临时的或无关紧要的。

例如,在下面的循环中,我们不需要访问正在运行的索引,我们可以使用“_”来表示它只是一个临时值:

>>> for _ in range(32):
...    print('Hello, World.')
로그인 후 복사
로그인 후 복사

你也可以在拆分(unpacking)表达式中将单个下划线用作“不关心的”变量,以忽略特定的值。 同样,这个含义只是“依照约定”,并不会在Python解释器中触发特殊的行为。 单个下划线仅仅是一个有效的变量名称,会有这个用途而已。

在下面的代码示例中,我将汽车元组拆分为单独的变量,但我只对颜色和里程值感兴趣。 但是,为了使拆分表达式成功运行,我需要将包含在元组中的所有值分配给变量。 在这种情况下,“_”作为占位符变量可以派上用场:

>>> car = ('red', 'auto', 12, 3812.4)
>>> color, _, _, mileage = car

>>> color
'red'
>>> mileage
3812.4
>>> _
12
로그인 후 복사
로그인 후 복사

除了用作临时变量之外,“_”是大多数Python REPL中的一个特殊变量,它表示由解释器评估的最近一个表达式的结果。

这样就很方便了,比如你可以在一个解释器会话中访问先前计算的结果,或者,你是在动态构建多个对象并与它们交互,无需事先给这些对象分配名字:

>>> 20 + 3
23
>>> _
23
>>> print(_)
23

>>> list()
[]
>>> _.append(1)
>>> _.append(2)
>>> _.append(3)
>>> _
[1, 2, 3]
로그인 후 복사
로그인 후 복사

위 내용은 Python에서 밑줄의 의미와 용도는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25 : Myrise에서 모든 것을 잠금 해제하는 방법
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

PS가 계속 로딩을 보여주는 이유는 무엇입니까? PS가 계속 로딩을 보여주는 이유는 무엇입니까? Apr 06, 2025 pm 06:39 PM

PS "로드"문제는 자원 액세스 또는 처리 문제로 인한 것입니다. 하드 디스크 판독 속도는 느리거나 나쁘다 : CrystalDiskinfo를 사용하여 하드 디스크 건강을 확인하고 문제가있는 하드 디스크를 교체하십시오. 불충분 한 메모리 : 고해상도 이미지 및 복잡한 레이어 처리에 대한 PS의 요구를 충족시키기 위해 메모리 업그레이드 메모리. 그래픽 카드 드라이버는 구식 또는 손상됩니다. 운전자를 업데이트하여 PS와 그래픽 카드 간의 통신을 최적화하십시오. 파일 경로는 너무 길거나 파일 이름에는 특수 문자가 있습니다. 짧은 경로를 사용하고 특수 문자를 피하십시오. PS 자체 문제 : PS 설치 프로그램을 다시 설치하거나 수리하십시오.

PS가 시작될 때 로딩 문제를 해결하는 방법은 무엇입니까? PS가 시작될 때 로딩 문제를 해결하는 방법은 무엇입니까? Apr 06, 2025 pm 06:36 PM

부팅 할 때 "로드"에 PS가 붙어있는 여러 가지 이유로 인해 발생할 수 있습니다. 손상되거나 충돌하는 플러그인을 비활성화합니다. 손상된 구성 파일을 삭제하거나 바꾸십시오. 불충분 한 메모리를 피하기 위해 불필요한 프로그램을 닫거나 메모리를 업그레이드하십시오. 하드 드라이브 독서 속도를 높이기 위해 솔리드 스테이트 드라이브로 업그레이드하십시오. 손상된 시스템 파일 또는 설치 패키지 문제를 복구하기 위해 PS를 다시 설치합니다. 시작 오류 로그 분석의 시작 과정에서 오류 정보를 봅니다.

PS가 파일을 열 때로드 문제를 해결하는 방법은 무엇입니까? PS가 파일을 열 때로드 문제를 해결하는 방법은 무엇입니까? Apr 06, 2025 pm 06:33 PM

"로드"는 PS에서 파일을 열 때 말더듬이 발생합니다. 그 이유에는 너무 크거나 손상된 파일, 메모리 불충분, 하드 디스크 속도가 느리게, 그래픽 카드 드라이버 문제, PS 버전 또는 플러그인 충돌이 포함될 수 있습니다. 솔루션은 다음과 같습니다. 파일 크기 및 무결성 확인, 메모리 증가, 하드 디스크 업그레이드, 그래픽 카드 드라이버 업데이트, 의심스러운 플러그인 제거 또는 비활성화 및 PS를 다시 설치하십시오. 이 문제는 PS 성능 설정을 점차적으로 확인하고 잘 활용하고 우수한 파일 관리 습관을 개발함으로써 효과적으로 해결할 수 있습니다.

설치 후 MySQL을 사용하는 방법 설치 후 MySQL을 사용하는 방법 Apr 08, 2025 am 11:48 AM

이 기사는 MySQL 데이터베이스의 작동을 소개합니다. 먼저 MySQLworkBench 또는 명령 줄 클라이언트와 같은 MySQL 클라이언트를 설치해야합니다. 1. MySQL-Uroot-P 명령을 사용하여 서버에 연결하고 루트 계정 암호로 로그인하십시오. 2. CreateABase를 사용하여 데이터베이스를 작성하고 데이터베이스를 선택하십시오. 3. CreateTable을 사용하여 테이블을 만들고 필드 및 데이터 유형을 정의하십시오. 4. InsertInto를 사용하여 데이터를 삽입하고 데이터를 쿼리하고 업데이트를 통해 데이터를 업데이트하고 DELETE를 통해 데이터를 삭제하십시오. 이러한 단계를 마스터하고 일반적인 문제를 처리하는 법을 배우고 데이터베이스 성능을 최적화하면 MySQL을 효율적으로 사용할 수 있습니다.

PS 페더 링은 어떻게 전환의 부드러움을 제어합니까? PS 페더 링은 어떻게 전환의 부드러움을 제어합니까? Apr 06, 2025 pm 07:33 PM

깃털 통제의 열쇠는 점진적인 성격을 이해하는 것입니다. PS 자체는 그라디언트 곡선을 직접 제어하는 ​​옵션을 제공하지 않지만 여러 깃털, 일치하는 마스크 및 미세 선택으로 반경 및 구배 소프트를 유연하게 조정하여 자연스럽게 전이 효과를 달성 할 수 있습니다.

MySQL은 지불해야합니다 MySQL은 지불해야합니다 Apr 08, 2025 pm 05:36 PM

MySQL에는 무료 커뮤니티 버전과 유료 엔터프라이즈 버전이 있습니다. 커뮤니티 버전은 무료로 사용 및 수정할 수 있지만 지원은 제한되어 있으며 안정성이 낮은 응용 프로그램에 적합하며 기술 기능이 강합니다. Enterprise Edition은 안정적이고 신뢰할 수있는 고성능 데이터베이스가 필요하고 지원 비용을 기꺼이 지불하는 응용 프로그램에 대한 포괄적 인 상업적 지원을 제공합니다. 버전을 선택할 때 고려 된 요소에는 응용 프로그램 중요도, 예산 책정 및 기술 기술이 포함됩니다. 완벽한 옵션은없고 가장 적합한 옵션 만 있으므로 특정 상황에 따라 신중하게 선택해야합니다.

PS 카드가 로딩 인터페이스에 있으면 어떻게해야합니까? PS 카드가 로딩 인터페이스에 있으면 어떻게해야합니까? Apr 06, 2025 pm 06:54 PM

PS 카드의로드 인터페이스는 소프트웨어 자체 (파일 손상 또는 플러그인 충돌), 시스템 환경 (DIFE 드라이버 또는 시스템 파일 손상) 또는 하드웨어 (하드 디스크 손상 또는 메모리 스틱 고장)로 인해 발생할 수 있습니다. 먼저 컴퓨터 자원이 충분한 지 확인하고 배경 프로그램을 닫고 메모리 및 CPU 리소스를 릴리스하십시오. PS 설치를 수정하거나 플러그인의 호환성 문제를 확인하십시오. PS 버전을 업데이트하거나 폴백합니다. 그래픽 카드 드라이버를 확인하고 업데이트하고 시스템 파일 확인을 실행하십시오. 위의 문제를 해결하면 하드 디스크 감지 및 메모리 테스트를 시도 할 수 있습니다.

MySQL 설치 후 데이터베이스 성능을 최적화하는 방법 MySQL 설치 후 데이터베이스 성능을 최적화하는 방법 Apr 08, 2025 am 11:36 AM

MySQL 성능 최적화는 설치 구성, 인덱싱 및 쿼리 최적화, 모니터링 및 튜닝의 세 가지 측면에서 시작해야합니다. 1. 설치 후 innodb_buffer_pool_size 매개 변수와 같은 서버 구성에 따라 my.cnf 파일을 조정해야합니다. 2. 과도한 인덱스를 피하기 위해 적절한 색인을 작성하고 Execution 명령을 사용하여 실행 계획을 분석하는 것과 같은 쿼리 문을 최적화합니다. 3. MySQL의 자체 모니터링 도구 (showprocesslist, showstatus)를 사용하여 데이터베이스 건강을 모니터링하고 정기적으로 백업 및 데이터베이스를 구성하십시오. 이러한 단계를 지속적으로 최적화함으로써 MySQL 데이터베이스의 성능을 향상시킬 수 있습니다.

See all articles