Python 객체 지향 프로그래밍에 대한 지식 요약

高洛峰
풀어 주다: 2017-02-18 10:14:22
원래의
1382명이 탐색했습니다.

Python은 처음부터 객체지향 언어였기 때문에 Python에서는 클래스와 객체를 쉽게 만들 수 있습니다. 다음 글에서는 Python 객체지향 프로그래밍에 대한 지식 포인트를 자세히 소개합니다. 필요한 친구들이 참고할 수 있습니다.

머리말

이전에 객체지향 프로그래밍 언어를 접해 본 적이 없다면 먼저 객체지향 언어의 몇 가지 기본 기능을 이해하고 기본 객체를 구성해야 할 수도 있습니다. Python에서 객체 지향 프로그래밍을 더 쉽게 배우는 데 도움이 될 것입니다.

다음으로 Python의 객체지향 프로그래밍에 대해 알아 보겠습니다.

클래스와 인스턴스

클래스는 객체의 정의이고, 인스턴스는 클래스에 정의된 객체의 구체적인 정보를 저장하는 "실제 객체"입니다.

클래스, 속성 및 메소드 명명 규칙

클래스 이름은 일반적으로 대문자로 시작합니다. 이는 표준 규칙이며 특히 인스턴스화(때때로 함수 호출처럼 보임) 중에 클래스를 식별하는 데 도움이 될 수 있습니다. 또한 데이터 속성(변수 또는 상수)은 데이터 값의 이름과 유사해야 하며, 메서드 이름은 해당 개체 또는 값의 동작을 나타내야 합니다.

또 다른 표현 방법은 데이터 값은 명사를 이름으로 사용해야 하고, 메소드는 술어(동사 + 목적어)를 사용해야 합니다. 데이터 항목은 작업할 개체이며 메서드는 프로그래머가 개체에 대해 수행하려는 작업을 나타내야 합니다.

정의된 클래스에서 "name", "phone" 및 "email"과 같은 데이터 값과 "updatePhone" 및 "updateEmail"과 같은 동작을 사용하여 이 지침을 대략적으로 따릅니다. 이를 종종 "mixedCase" 또는 "camelCase"라고 합니다. Python 사양에서는 "update_phone", "update_email"과 같이 밑줄이 포함된 카멜 표기법을 사용할 것을 권장합니다. 클래스 이름도 "AddrBookEntry", "RepairShop" 등과 같이 주의 깊게 지정해야 합니다. 좋은 이름입니다.

class AddrBookEntry(object):

 def __init__(self, name, phone, email):
 self.name = name
 self.phone = phone
 self.email = email

 def update_phone(self, phone):
 self.phone = phone

 def update_email(self. email):
 self.email = email
로그인 후 복사

신형 클래스와 기존 클래스

신형 클래스와 클래식 클래스 선언의 가장 큰 차이점은 모두 새로운 스타일 클래스는 적어도 하나의 상위 클래스를 상속해야 합니다. 상속할 클래스가 없으면 객체 클래스를 상속받을 수 있습니다. 객체는 "모든 클래스의 어머니"이며 모든 클래스 상속 구조의 최상위에 위치합니다. 객체의 직접적 또는 간접적 서브클래싱이 없으면 클래식 클래스가 정의됩니다. 즉, 상위 클래스가 지정되지 않거나 서브클래싱되는 기본 클래스에 상위 클래스가 없는 경우 클래식 클래스가 생성됩니다.

Python3에서 정의된 클래스는 기본적으로 새로운 스타일의 클래스입니다. Python2에서 새로운 스타일의 클래스를 정의하려면 객체를 상속하거나 새로운 스타일의 클래스를 상속받아야 합니다.

자체 변수

클래스의 메소드는 일반 함수와 한 가지 특별한 차이점이 있습니다. 즉, 추가로 첫 번째 매개변수 이름이 있어야 하지만 이 메소드 호출 시에는 필요하지 않습니다. 이 매개변수를 할당하면 Python이 이 값을 제공합니다. 이 특정 변수는 객체 자체를 참조하며 관례적으로 이름은 self입니다. 이 매개변수에 임의의 이름을 지정할 수 있지만 self라는 이름을 사용하는 것이 강력히 권장되며 다른 이름은 더 이상 사용되지 않습니다.

__init__() 메서드

__init__()는 클래스 생성자와 유사하지만 실제로 생성자는 아닙니다. Python은 인스턴스를 생성한 후 인스턴스화 프로세스 중에 __init__() 메서드를 호출합니다. 클래스가 인스턴스화되면 초기 값을 설정하거나 일부 예비 진단 코드를 실행하는 등의 추가 동작을 정의할 수 있습니다. 인스턴스가 생성되면 인스턴스화 호출은 인스턴스로 반환되기 전에 특정 작업이나 설정을 수행합니다.

바운드 및 언바운드 메서드

Python에서 클래스에 액세스하는 메서드는 인스턴스를 통해 직접 액세스하거나 클래스를 통해 직접 액세스할 수 있습니다. 그러나 Python에서는 인스턴스 없이 메서드를 호출할 수 없도록 엄격히 요구합니다. 이 제한 사항은 Python에서 바인딩으로 설명하는 것입니다. 즉, 메서드를 직접 호출하려면 인스턴스에 바인딩해야 합니다. 바인딩되지 않은 메서드를 호출할 수 있지만 호출이 성공하도록 하려면 인스턴스 개체를 명시적으로 제공해야 합니다. 그러나 바인딩 여부에 관계없이 메서드는 거의 항상 인스턴스를 통해 호출되지만 메서드가 발견된 클래스의 고유 속성입니다. Python의 클래스 메서드도 객체입니다. 클래스를 통해 직접 액세스하는 메서드를 "언바운드 메서드"라고 하고, 인스턴스를 통해 액세스하는 메서드를 "바운드 메서드"라고 한다고 간단히 이해하면 됩니다.

1. 언바운드 클래스 메서드: No self

클래스를 통해 메서드를 참조하면 바인딩되지 않은 메서드 개체가 반환됩니다. 이를 호출하려면 인스턴스를 첫 번째 인수로 명시적으로 제공해야 합니다.

2. 바인딩된 인스턴스 메서드: 인스턴스 액세스 메서드를 통해 바인딩된 메서드 개체를 반환하는 self

가 있습니다. Python은 자동으로 인스턴스를 메서드에 바인딩하므로 호출할 때 인스턴스 매개 변수를 전달할 필요가 없습니다.

예:

class Test:
 def func(self, message):
 print message

object1 = Test()
x = object1.func
x("绑定方法对象,实例是隐藏的")

t = Test.func
t(object1, "未绑定方法对象,需要传递一个实例")
# t("未绑定方法对象,需要传递一个实例") # 错误的调用
로그인 후 복사

클래스 속성 및 인스턴스 속성

类属性仅是与类相关的数据值,和实例属性不同,类属性和实例无关。这些值像静态成员那样被引用,即使在多次实例化中调用类,它们的值都保持不变。不管如何,静态成员不会因为实例而改变它们的值,除非实例中显式改变它们的值。 实例属性与类属性的比较,类似于自动变量和静态变量,但这只是笼统的类推。在你对自动变量和静态变量还不是很熟的情况下,不要深究这些。

类和实例都是名字空间。类是类属性的名字空间,实例则是实例属性的。

可采用类来访问类属性,如果实例没有同名的属性的话,也可以用实例来访问。

私有化

Python并不直接支持私有方式,而要靠程序员自己把握在外部进行特性修改的时机。

为了让方法或者特性变为私有(从外部无法访问),只要在它的名字前面加上双下划线即可。由双下划线 __ 开始的属性在运行时被“混淆”,所以直接访问是不允许的。

实际上,在 Python 带有双下划线的属性或方法并非正真意义上的私有,它们仍然可以被访问。在类的内部定义中,所有以双下划线开始的名字都被“翻译”成前面加上单下划线和类名的形式:

>>> class TestObj(object):
... __war = "world"
... 
... def __init__(self):
...  self.__har = "hello"
...  
... def __foo(self):
...  print(self.__har + self.__war)
...  
... 
... 
>>> t = TestObj()
>>> dir(t)
['_TestObj__foo', '_TestObj__har', '_TestObj__war', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getat
tribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__
', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
>>> t.__war
Traceback (most recent call last):
 File "<input>", line 1, in <module>
 t.__war
AttributeError: 'TestObj' object has no attribute '__war'
>>> t.__har
Traceback (most recent call last):
 File "<input>", line 1, in <module>
 t.__har
AttributeError: 'TestObj' object has no attribute '__har'
>>> t.foo()
Traceback (most recent call last):
 File "<input>", line 1, in <module>
 t.foo()
AttributeError: 'TestObj' object has no attribute 'foo'
>>> t._TestObj__war
'world'
>>> t._TestObj__har
'hello'
>>> t._TestObj__foo()
helloworld
로그인 후 복사

__slots__ 类属性

正常情况下,当我们定义了一个 class,创建了一个 class 的实例后,我们可以给该实例绑定任何属性和方法,这就是动态语言的灵活性。在 Python 中默认用字典来存储实例的属性。

示例:

>>> class A():
... pass
... 
>>> a = A()
>>> a.name = "huoty"
>>> a.age = 25
>>> print a.name
huoty
>>> print a.age
25
>>> a.__dict__
{'age': 25, 'name': 'huoty'}
로그인 후 복사

字典位于实例的“心脏” 。 __dict__属性跟踪所有实例属性。举例来说,你有一个实例 inst,它有一个属性 foo,那使用 inst.foo 来访问它与使用 inst.__dict__['foo'] 来访问是一致的。

字典会占据大量内存,如果你有一个属性数量很少的类,但有很多实例,那么正好是这种情况。为内存上的考虑,可以使用 __slots__ 属性来替代 __dict__ 。

, __slots__ 是新式类的特性。基本上, __slots__ 是一个类变量,由一序列对象组成,由所有合法标识构成的实例属性的集合来表示。它可以是一个列表,元组或可迭代对象。也可以是标识实例能拥有的唯一的属性的简单字符串。任何试图创建一个其名不在 __slots__ 中的名字的实例属性都将导致 AttributeError 异常:

>>> class SlotedClass(object):
... __slots__ = ("foo", "bar")
... 
... 
>>> c = SlotedClass()
>>> c.foo = 42
>>> c.bar = "hello"
>>> c.goo = "don't think so"
Traceback (most recent call last):
 File "<input>", line 1, in <module>
AttributeError: 'SlotedClass' object has no attribute 'goo'
로그인 후 복사

这种特性的主要目的是节约内存。其副作用是某种类型的"安全",它能防止用户随心所欲的动态增加实例属性。带 __slots__ 属性的类定义不会存在 __dict__ 了(除非你在 __slots__ 中增加 __dict__ 元素)。


更多关于Python面向对象编程的知识点总结相关文章请关注PHP中文网!


관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿