Python에서 self를 사용하는 방법
Python에서 self의 사용법을 소개하기 전에 먼저 Python의 클래스와 인스턴스를 소개하겠습니다.
객체 지향의 가장 중요한 개념은 클래스와 인스턴스라는 것을 알고 있습니다. 클래스는 추상 학생과 같은 추상 템플릿입니다. 학생 수업으로. 인스턴스는 클래스를 기반으로 생성된 특정 "객체"입니다. 각 객체는 클래스에서 동일한 메서드를 상속하지만 해당 데이터는 다를 수 있습니다.
1. Python에서 클래스는 다음과 같이 정의됩니다.
class Student(object): pass
(Object)는 클래스가 상속되는 클래스를 나타냅니다.
2. 인스턴스: 클래스가 정의된 후 Student 클래스를 통해 인스턴스를 생성할 수 있습니다. 클래스 이름 + ():
student = Student()
3. 인스턴스를 생성할 때 바인딩되어야 한다고 생각되는 속성을 강제로 채웁니다. 여기서는 Python에 내장된 메서드인 __init__
메서드를 사용합니다. 예를 들어 Student 클래스에서는 이름 및 점수와 같은 속성을 여기에 연결합니다. __init__
方法,例如在Student类时,把name、score等属性绑上去:
class Student(object): def __init__(self, name, score): self.name = name self.score = score
这里注意:(1)、__init__
方法的第一参数永远是self
,表示创建的类实例本身,因此,在__init__
方法内部,就可以把各种属性绑定到self,因为self就指向创建的实例本身。(2)、有了__init__
方法,在创建实例的时候,就不能传入空的参数了,必须传入与__init__
方法匹配的参数,但self不需要传,Python解释器会自己把实例变量传进去:
>>>student = Student("Hugh", 99) >>>student.name "Hugh" >>>student.score 99
另外,这里self
就是指类本身,self.name
就是Student
类的属性变量,是Student
类所有。而name
是外部传来的参数,不是Student
类所自带的。故,self.name = name
的意思就是把外部传来的参数name
的值赋值给Student类自己的属性变量self.name
。
4、和普通数相比,在类中定义函数只有一点不同,就是第一参数永远是类的本身实例变量self
,并且调用时,不用传递该参数。除此之外,类的方法(函数)和普通函数没啥区别,你既可以用默认参数、可变参数或者关键字参数(*args是可变参数,args接收的是一个tuple,**kw是关键字参数,kw接收的是一个dict)。
5、既然Student类实例本身就拥有这些数据,那么要访问这些数据,就没必要从外面的函数去访问,而可以直接在Student类的内部定义访问数据的函数(方法),这样,就可以把”数据”封装起来。这些封装数据的函数是和Student类本身是关联起来的,称之为类的方法:
class Student(obiect): def __init__(self, name, score): self.name = name self.score = score def print_score(self): print "%s: %s" % (self.name, self.score)
>>>student = Student("Hugh", 99) >>>student.print_score Hugh: 99
这样一来,我们从外部看Student类,就只需要知道,创建实例需要给出name和score。而如何打印,都是在Student类的内部定义的,这些数据和逻辑被封装起来了,调用很容易,但却不知道内部实现的细节。
如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线,在Python中,实例的变量名如果以开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问,所以,我们把Student类改一改:
class Student(object): def __init__(self, name, score): self.__name = name self.__score = score def print_score(self): print "%s: %s" %(self.__name,self.__score)
改完后,对于外部代码来说,没什么变动,但是已经无法从外部访问实例变量.__name
和实例变量.__score
了:
>>> student = Student('Hugh', 99) >>> student.__name Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Student' object has no attribute '__name'
这样就确保了外部代码不能随意修改对象内部的状态,这样通过访问限制的保护,代码更加健壮。
但是如果外部代码要获取name和score怎么办?可以给Student类增加get_name和get_score这样的方法:
class Student(object): ... def get_name(self): return self.__name def get_score(self): return self.__score
如果又要允许外部代码修改score怎么办?可以给Student类增加set_score方法:
class Student(object): ... def set_score(self, score): self.__score = score
需要注意的是,在Python中,变量名类似__xxx__
的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是private变量,所以,不能用__name__
、__score__
这样的变量名。
有些时候,你会看到以一个下划线开头的实例变量名,比如_name,这样的实例变量外部是可以访问的,但是,按照约定俗成的规定,当你看到这样的变量时,意思就是,“虽然我可以被访问,但是,请把我视为私有变量,不要随意访问”。
封装的另一个好处是可以随时给Student类增加新的方法,比如:get_grade
:
class Student(object): ... def get_grade(self): if self.score >= 90: return 'A' elif self.score >= 60: return 'B' else: return 'C'
同样的,get_grade
>>> student.get_grade() 'A'
__init__< /code> 메소드의 첫 번째 매개변수는 항상 <code>self
이며, 이는 생성된 클래스 인스턴스 자체를 나타냅니다. code> 메소드를 사용하면 self가 생성된 인스턴스 자체를 가리키기 때문에 다양한 속성이 self에 바인딩됩니다. (2) __init__
메서드를 사용하면 인스턴스 생성 시 빈 매개변수를 전달할 수 없습니다. __init__
메서드와 일치하는 매개변수를 전달해야 하지만 self는 그럴 필요가 없습니다. 전달하면 Python 인터프리터가 인스턴스 변수를 자체적으로 전달합니다. 🎜class Test: def ppr(self): print(self) print(self.__class__) t = Test() t.ppr() 执行结果: <__main__.Test object at 0x000000000284E080> <class '__main__.Test'>
self
는 클래스 자체를 참조하고 self.name
은 입니다. Student< /code> 클래스의 속성 변수는 <code>Student
클래스가 소유합니다. 그리고 name
은 Student
클래스와 함께 제공되는 매개변수가 아닌 외부 매개변수입니다. 따라서 self.name = name
은 외부 매개변수 name
의 값을 Student 클래스 자체 속성 변수 self.name
에 할당한다는 의미입니다. 🎜🎜4 일반 숫자와 비교할 때 클래스에서 함수를 정의하는 것의 유일한 차이점은 첫 번째 매개변수가 항상 클래스 자체의 인스턴스 변수self</입니다. code>, 호출 시 이 매개변수를 전달하지 마십시오. 또한 클래스 메소드(함수)는 일반 함수와 다르지 않습니다. <strong>기본 매개변수, 변수 매개변수 또는 키워드 매개변수</strong>를 사용할 수 있습니다(<strong>*args는 변수 매개변수이고 args는 튜플을 받습니다</strong). >, <strong>**kw는 키워드 매개변수이고 kw는 dict를 받습니다</strong>). 🎜🎜5. <strong>Student</strong> 클래스 인스턴스 자체가 이러한 데이터를 소유하므로 이러한 데이터에 액세스하기 위해 외부 함수에서 액세스할 필요가 없습니다. 대신 데이터에 액세스하는 함수를 클래스 내부에서 직접 정의할 수 있습니다. 학생 클래스.(방법) 이러한 방식으로 "데이터"를 캡슐화할 수 있습니다. 데이터를 캡슐화하는 이러한 함수는 Student 클래스 자체와 연결되어 있으며 클래스 메서드라고 합니다. 🎜<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>class Test:
def ppr():
print(self)
t = Test()
t.ppr()</pre><div class="contentsignin">로그인 후 복사</div></div><div class="contentsignin">로그인 후 복사</div></div><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>class Test:
def ppr():
print(__class__)
Test.ppr()
运行结果:
<class &#39;__main__.Test&#39;></pre><div class="contentsignin">로그인 후 복사</div></div><div class="contentsignin">로그인 후 복사</div></div>🎜 이런 식으로 Student 클래스를 외부에서 볼 때 이름과 점수만 알면 됩니다. 인스턴스를 생성하도록 제공됩니다. 인쇄 방법은 Student 클래스 내에서 정의됩니다. <strong>이러한 데이터와 논리는 캡슐화되어 호출하기가 쉽지만 내부 구현의 세부 사항은 알 수 없습니다. </strong>🎜🎜내부 속성이 외부에서 액세스되는 것을 방지하려면 속성 이름 앞에 두 개의 밑줄 <strong>을 추가하면 됩니다. Python에서 인스턴스의 변수 이름이 </strong>로 시작하는 경우 프라이빗 변수(private)는 내부적으로만 접근 가능하고 외부에서는 접근이 불가능합니다. 따라서 Student 클래스를 변경합니다: 🎜<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>class Parent:
def pprt(self):
print(self)
class Child(Parent):
def cprt(self):
print(self)
c = Child()
c.cprt()
c.pprt()
p = Parent()
p.pprt()</pre><div class="contentsignin">로그인 후 복사</div></div><div class="contentsignin">로그인 후 복사</div></div>🎜수정 후 외부 코드는 변경되지 않지만 외부에서는 인스턴스에 접근할 수 없습니다. 변수 <code>.__name
및 인스턴스 변수 .__score
는 다음과 같습니다. 🎜class Desc: def __get__(self, ins, cls): print('self in Desc: %s ' % self ) print(self, ins, cls) class Test: x = Desc() def prt(self): print('self in Test: %s' % self) t = Test() t.prt() t.x
self in Test: <__main__.Test object at 0x00000000022570B8> self in Desc: <__main__.Desc object at 0x000000000223E208> <__main__.Desc object at 0x000000000223E208> None <class '__main__.Test'>
__xxx__
와 유사합니다. 즉, 이중 밑줄로 시작하고 이중 밑줄로 끝나는 이름입니다. 밑줄은 특수 변수이므로 전용 변수가 아닌 특수 변수에 직접 접근할 수 있으므로 __name__
, __score__
등의 변수 이름은 사용할 수 없습니다. 🎜🎜때때로 _name과 같이 밑줄로 시작하는 인스턴스 변수를 볼 수 있습니다. 이러한 인스턴스 변수는 외부에서 액세스할 수 있지만 관례에 따르면 이러한 변수는 "접근할 수 있지만"이라는 의미입니다. , 저를 개인 변수로 취급하시고 임의로 접근하지 마시기 바랍니다." 🎜🎜캡슐화의 또 다른 이점은 언제든지 Student 클래스에 새로운 메서드를 추가할 수 있다는 것입니다. get_grade
:🎜rrreee🎜마찬가지로 get_grade< /code> 내부 구현 세부 사항을 알지 못해도 인스턴스 변수에서 직접 메서드를 호출할 수 있습니다. 🎜<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>>>> student.get_grade()
&#39;A&#39;</pre><div class="contentsignin">로그인 후 복사</div></div><div class="contentsignin">로그인 후 복사</div></div><p>6、<code>self
的仔细用法(1)、self代表类的实例,而非类。
class Test: def ppr(self): print(self) print(self.__class__) t = Test() t.ppr() 执行结果: <__main__.Test object at 0x000000000284E080> <class '__main__.Test'>
从上面的例子中可以很明显的看出,self代表的是类的实例。而self.__class__
则指向类。
注意:把self换成this,结果也一样,但Python中最好用约定俗成的self。
(2)、self可以不写吗?
在Python解释器的内部,当我们调用t.ppr()时,实际上Python解释成Test.ppr(t),也就是把self替换成了类的实例。
class Test: def ppr(): print(self) t = Test() t.ppr()
运行结果如下:
Traceback (most recent call last):
File "cl.py", line 6, in
t.ppr()
TypeError: ppr() takes 0 positional arguments but 1 was given
运行时提醒错误如下:ppr在定义时没有参数,但是我们运行时强行传了一个参数。
由于上面解释过了t.ppr()等同于Test.ppr(t),所以程序提醒我们多传了一个参数t。
这里实际上已经部分说明了self
在定义时不可以省略。
当然,如果我们的定义和调用时均不传类实例是可以的,这就是类方法。
class Test: def ppr(): print(__class__) Test.ppr() 运行结果: <class '__main__.Test'>
(3)、在继承时,传入的是哪个实例,就是那个传入的实例,而不是指定义了self的类的实例。
class Parent: def pprt(self): print(self) class Child(Parent): def cprt(self): print(self) c = Child() c.cprt() c.pprt() p = Parent() p.pprt()
运行结果:
<__main__.Child object at 0x0000000002A47080>
<__main__.Child object at 0x0000000002A47080>
<__main__.Parent object at 0x0000000002A47240>
解释:
运行c.cprt()时应该没有理解问题,指的是Child类的实例。
但是在运行c.pprt()时,等同于Child.pprt(c),所以self指的依然是Child类的实例,由于self中没有定义pprt()方法,所以沿着继承树往上找,发现在父类Parent中定义了pprt()方法,所以就会成功调用。
(4)、在描述符类中,self指的是描述符类的实例
class Desc: def __get__(self, ins, cls): print('self in Desc: %s ' % self ) print(self, ins, cls) class Test: x = Desc() def prt(self): print('self in Test: %s' % self) t = Test() t.prt() t.x
运行结果如下:
self in Test: <__main__.Test object at 0x0000000002A570B8>
self in Desc: <__main__.Desc object at 0x000000000283E208>
<__main__.Desc object at 0x000000000283E208> <__main__.Test object at 0x0000000002A570B8>
这里主要的疑问应该在:Desc类中定义的self不是应该是调用它的实例t吗?怎么变成了Desc类的实例了呢?
因为这里调用的是t.x,也就是说是Test类的实例t的属性x,由于实例t中并没有定义属性x,所以找到了类属性x,而该属性是描述符属性,为Desc类的实例而已,所以此处并没有顶用Test的任何方法。
那么我们如果直接通过类来调用属性x也可以得到相同的结果。
下面是把t.x改为Test.x运行的结果。
self in Test: <__main__.Test object at 0x00000000022570B8> self in Desc: <__main__.Desc object at 0x000000000223E208> <__main__.Desc object at 0x000000000223E208> None <class '__main__.Test'>
위 내용은 Python에서 self를 사용하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

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

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

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

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

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

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

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

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

뜨거운 주제











이 기사는 데비안 시스템에서 Apache Logs를 분석하여 웹 사이트 성능을 향상시키는 방법을 설명합니다. 1. 로그 분석 기본 사항 Apache Log는 IP 주소, 타임 스탬프, 요청 URL, HTTP 메소드 및 응답 코드를 포함한 모든 HTTP 요청의 자세한 정보를 기록합니다. 데비안 시스템 에서이 로그는 일반적으로 /var/log/apache2/access.log 및 /var/log/apache2/error.log 디렉토리에 있습니다. 로그 구조를 이해하는 것은 효과적인 분석의 첫 번째 단계입니다. 2. 로그 분석 도구 다양한 도구를 사용하여 Apache 로그를 분석 할 수 있습니다.

Python은 게임 및 GUI 개발에서 탁월합니다. 1) 게임 개발은 Pygame을 사용하여 드로잉, 오디오 및 기타 기능을 제공하며 2D 게임을 만드는 데 적합합니다. 2) GUI 개발은 Tkinter 또는 PYQT를 선택할 수 있습니다. Tkinter는 간단하고 사용하기 쉽고 PYQT는 풍부한 기능을 가지고 있으며 전문 개발에 적합합니다.

PHP와 Python은 각각 고유 한 장점이 있으며 프로젝트 요구 사항에 따라 선택합니다. 1.PHP는 웹 개발, 특히 웹 사이트의 빠른 개발 및 유지 보수에 적합합니다. 2. Python은 간결한 구문을 가진 데이터 과학, 기계 학습 및 인공 지능에 적합하며 초보자에게 적합합니다.

이 기사에서는 DDOS 공격 탐지 방법에 대해 설명합니다. "Debiansniffer"의 직접적인 적용 사례는 발견되지 않았지만 DDOS 공격 탐지에 다음과 같은 방법을 사용할 수 있습니다. 효과적인 DDOS 공격 탐지 기술 : 트래픽 분석을 기반으로 한 탐지 : 갑작스런 트래픽 성장, 특정 포트에서의 연결 감지 등의 비정상적인 네트워크 트래픽 패턴을 모니터링하여 DDOS 공격을 식별합니다. 예를 들어, Pyshark 및 Colorama 라이브러리와 결합 된 Python 스크립트는 실시간으로 네트워크 트래픽을 모니터링하고 경고를 발행 할 수 있습니다. 통계 분석에 기반한 탐지 : 데이터와 같은 네트워크 트래픽의 통계적 특성을 분석하여

데비안 시스템의 readdir 함수는 디렉토리 컨텐츠를 읽는 데 사용되는 시스템 호출이며 종종 C 프로그래밍에 사용됩니다. 이 기사에서는 ReadDir를 다른 도구와 통합하여 기능을 향상시키는 방법을 설명합니다. 방법 1 : C 언어 프로그램을 파이프 라인과 결합하고 먼저 C 프로그램을 작성하여 readDir 함수를 호출하고 결과를 출력하십시오.#포함#포함#포함#포함#includinTmain (intargc, char*argv []) {dir*dir; structdirent*entry; if (argc! = 2) {

제한된 시간에 Python 학습 효율을 극대화하려면 Python의 DateTime, Time 및 Schedule 모듈을 사용할 수 있습니다. 1. DateTime 모듈은 학습 시간을 기록하고 계획하는 데 사용됩니다. 2. 시간 모듈은 학습과 휴식 시간을 설정하는 데 도움이됩니다. 3. 일정 모듈은 주간 학습 작업을 자동으로 배열합니다.

이 기사에서는 Debian 시스템에서 NginxSSL 인증서를 업데이트하는 방법에 대해 안내합니다. 1 단계 : CertBot을 먼저 설치하십시오. 시스템에 CERTBOT 및 PYTHON3-CERTBOT-NGINX 패키지가 설치되어 있는지 확인하십시오. 설치되지 않은 경우 다음 명령을 실행하십시오. sudoapt-getupdatesudoapt-getinstallcertbotpython3-certbot-nginx 2 단계 : 인증서 획득 및 구성 rectbot 명령을 사용하여 nginx를 획득하고 nginx를 구성하십시오.

데비안 시스템에서 HTTPS 서버를 구성하려면 필요한 소프트웨어 설치, SSL 인증서 생성 및 SSL 인증서를 사용하기 위해 웹 서버 (예 : Apache 또는 Nginx)를 구성하는 등 여러 단계가 포함됩니다. 다음은 Apacheweb 서버를 사용하고 있다고 가정하는 기본 안내서입니다. 1. 필요한 소프트웨어를 먼저 설치하고 시스템이 최신 상태인지 확인하고 Apache 및 OpenSSL을 설치하십시오 : Sudoaptupdatesudoaptupgradesudoaptinsta
