Latest web development tutorials

งูหลามเชิงวัตถุ

งูใหญ่ได้รับการออกแบบตั้งแต่เริ่มต้นเป็นภาษาเชิงวัตถุและเป็นเช่นนี้สร้างคลาสและวัตถุในหลามเป็นเรื่องง่ายมาก ส่วนนี้เราจะมีรายละเอียดการเขียนโปรแกรมเชิงวัตถุในหลาม

หากคุณไม่ได้รับการสัมผัสกับวัตถุที่มุ่งเน้นการเขียนโปรแกรมภาษาแล้วคุณอาจจะต้องเข้าใจก่อนบางส่วนของคุณสมบัติพื้นฐานของภาษาเชิงวัตถุที่เกิดขึ้นในใจภายในแนวคิดพื้นฐานของวัตถุซึ่งจะช่วยให้คุณได้ง่ายขึ้นเรียนรู้หลาม การเขียนโปรแกรมเชิงวัตถุ

ถัดไปให้ใช้ความเข้าใจที่ง่ายของเชิงวัตถุภายใต้คุณสมบัติพื้นฐานบางอย่าง


ภาพรวมเทคโนโลยีเชิงวัตถุ

  • คลาส (Class): ใช้เพื่ออธิบายคอลเลกชันที่มีคุณสมบัติและวิธีของวัตถุ มันกำหนดชุดของคุณสมบัติและวิธีการที่พบบ่อยในแต่ละวัตถุ วัตถุกรณีของการเรียน
  • ตัวแปรระดับ: ตัวแปรระดับเป็นเรื่องธรรมดาทั่ววัตถุ instantiated ตัวแปรระดับที่กำหนดไว้และภายนอกฟังก์ชั่นในชั้นเรียนใน ตัวแปรระดับปกติไม่ได้ใช้เป็นตัวแปรเช่น
  • ข้อมูลสมาชิก: ตัวแปรระดับหรือตัวแปรเช่นสำหรับการเชื่อมโยงการเรียนการประมวลผลข้อมูลและวัตถุเช่น
  • การแทนที่: ถ้าคุณไม่สามารถตอบสนองความต้องการของ subclass สืบทอดมาจากวิธีการเรียนผู้ปกครองก็สามารถเขียนเป็นกระบวนการที่เรียกว่าวิธีการซ้อนทับ (แทนที่) ยังเป็นที่รู้จักวิธีการเอาชนะ
  • ตัวอย่างของตัวแปร: ตัวแปรที่กำหนดไว้ในวิธีการเฉพาะบทบาทของชั้นเรียนของอินสแตนซ์ปัจจุบัน
  • มรดก: นั่นคือคลาสที่ได้รับ (ชั้นมา) สืบทอดชั้นฐาน (ชั้นฐาน) เขตข้อมูลและวิธีการ มรดกยังช่วยให้วัตถุชั้นมาเป็นวัตถุรักษาชั้นฐาน ตัวอย่างเช่นมีเช่นการออกแบบ: ประเภทของวัตถุที่ได้รับมาจากชั้นสุนัขสัตว์ซึ่งเป็นอะนาล็อก "เป็น (เป็น-A)" ความสัมพันธ์ (รูปตัวอย่างเช่นเป็นสัตว์สุนัข)
  • อินสแตนซ์: สร้างตัวอย่างของชั้นที่ชั้นวัตถุที่เฉพาะเจาะจง
  • วิธีการ: ฟังก์ชั่นระดับที่กำหนดไว้
  • เช่นโครงสร้างข้อมูลผ่านการกำหนดชั้น: วัตถุ วัตถุข้อมูลรวมถึงสองสมาชิก (ชั้นและอินสแตนซ์ตัวแปร) และวิธีการ

สร้างชั้นเรียน

ใช้คำสั่งชั้นเรียนเพื่อสร้างชั้นใหม่หลังเลิกเรียนและชื่อชั้นลงท้ายด้วยลำไส้ใหญ่ตัวอย่างต่อไปนี้:

class ClassName:
   '类的帮助信息'   #类文档字符串
   class_suite  #类体

ระดับความช่วยเหลือสามารถดูได้โดย ClassName .__ doc__

class_suite ประกอบด้วยสมาชิกของชั้นวิธีแอตทริบิวต์ข้อมูล

ตัวอย่าง

ต่อไปนี้เป็นเช่นชั้นหลามง่าย:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

class Employee:
   '所有员工的基类'
   empCount = 0

   def __init__(self, name, salary):
      self.name = name
      self.salary = salary
      Employee.empCount += 1
   
   def displayCount(self):
     print "Total Employee %d" % Employee.empCount

   def displayEmployee(self):
      print "Name : ", self.name,  ", Salary: ", self.salary
  • ตัวแปร empCount เป็นตัวแปรระดับค่าของมันจะถูกใช้ร่วมกันระหว่างทุกกรณีของชั้นนี้ คุณสามารถใช้การเข้าถึง Employee.empCount ภายในชั้นเรียนหรือชั้นนอก
  • วิธีแรก __init __ () วิธีการเป็นวิธีพิเศษคอนสตรัคหรือการเริ่มต้นเรียนวิธีการที่เรียกว่าเมื่อมีการสร้างอินสแตนซ์ของคลาสนี้จะเรียกวิธี

สร้างตัวอย่างของวัตถุ

เพื่อสร้างอินสแตนซ์ของชั้นคุณสามารถใช้ชื่อของชั้นและยอมรับวิธีการพารามิเตอร์ __init__

"创建 Employee 类的第一个对象"
emp1 = Employee("Zara", 2000)
"创建 Employee 类的第二个对象"
emp2 = Employee("Manni", 5000)

คุณสมบัติการเข้า

คุณสามารถใช้จุด (.) ที่ดินในการเข้าถึงวัตถุ การเข้าถึงตัวแปรระดับที่มีชื่อของชั้นดังต่อไปนี้:

emp1.displayEmployee()
emp2.displayEmployee()
print "Total Employee %d" % Employee.empCount

ตัวอย่างที่สมบูรณ์:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

class Employee:
   '所有员工的基类'
   empCount = 0

   def __init__(self, name, salary):
      self.name = name
      self.salary = salary
      Employee.empCount += 1
   
   def displayCount(self):
     print "Total Employee %d" % Employee.empCount

   def displayEmployee(self):
      print "Name : ", self.name,  ", Salary: ", self.salary

"创建 Employee 类的第一个对象"
emp1 = Employee("Zara", 2000)
"创建 Employee 类的第二个对象"
emp2 = Employee("Manni", 5000)
emp1.displayEmployee()
emp2.displayEmployee()
print "Total Employee %d" % Employee.empCount

รันโค้ดข้างต้นออกผลมีดังนี้

Name :  Zara ,Salary:  2000
Name :  Manni ,Salary:  5000
Total Employee 2

คุณสามารถเพิ่มลบแก้ไขคุณสมบัติของชั้นดังต่อไปนี้:

emp1.age = 7  # 添加一个 'age' 属性
emp1.age = 8  # 修改 'age' 属性
del emp1.age  # 删除 'age' 属性

นอกจากนี้คุณยังสามารถเข้าถึงคุณสมบัติการใช้งานฟังก์ชั่นดังต่อไปนี้:

  • getattr (obj ชื่อ [เริ่มต้น]): วัตถุเข้าถึงสถานที่ให้บริการ
  • hasattr (obj ชื่อ): ตรวจสอบว่ามีแอตทริบิวต์
  • setattr (obj ชื่อค่า): ตั้งค่าสถานที่ให้บริการ ถ้าคุณสมบัติไม่อยู่สร้างคุณสมบัติใหม่
  • delattr (obj ชื่อ): ลบแอตทริบิวต์
hasattr(emp1, 'age')    # 如果存在 'age' 属性返回 True。
getattr(emp1, 'age')    # 返回 'age' 属性的值
setattr(emp1, 'age', 8) # 添加属性 'age' 值为 8
delattr(empl, 'age')    # 删除属性 'age'

งูหลามแอตทริบิวต์ชั้นในตัว

  • __dict__: คุณลักษณะของชั้น (รวมถึงพจนานุกรมข้อมูลแอตทริบิวต์องค์ประกอบ class)
  • __doc__: คลาสสตริงเอกสาร
  • __name__: ชื่อชั้น
  • __module__: โมดูลที่กำหนดชั้น (ชื่อเต็มคือ '. __main __ className' ถ้าชั้นตั้งอยู่ใน mymod โมดูลนำเข้าแล้ว className .__ mymod เท่ากับ module__)
  • __bases__: เรียนทุกองค์ประกอบหลัก (ประกอบไปด้วยผู้ปกครองชั้นเรียนประกอบด้วย tuples ทั้งหมด)

งูหลามสายในตัวตัวอย่างแอตทริบิวต์ระดับมีดังนี้

#!/usr/bin/python
# -*- coding: UTF-8 -*-

class Employee:
   '所有员工的基类'
   empCount = 0

   def __init__(self, name, salary):
      self.name = name
      self.salary = salary
      Employee.empCount += 1
   
   def displayCount(self):
     print "Total Employee %d" % Employee.empCount

   def displayEmployee(self):
      print "Name : ", self.name,  ", Salary: ", self.salary

print "Employee.__doc__:", Employee.__doc__
print "Employee.__name__:", Employee.__name__
print "Employee.__module__:", Employee.__module__
print "Employee.__bases__:", Employee.__bases__
print "Employee.__dict__:", Employee.__dict__

รันโค้ดข้างต้นออกผลมีดังนี้

Employee.__doc__: 所有员工的基类
Employee.__name__: Employee
Employee.__module__: __main__
Employee.__bases__: ()
Employee.__dict__: {'__module__': '__main__', 'displayCount': <function displayCount at 0x10a939c80>, 'empCount': 0, 'displayEmployee': <function displayEmployee at 0x10a93caa0>, '__doc__': '\xe6\x89\x80\xe6\x9c\x89\xe5\x91\x98\xe5\xb7\xa5\xe7\x9a\x84\xe5\x9f\xba\xe7\xb1\xbb', '__init__': <function __init__ at 0x10a939578>}

วัตถุหลามถูกทำลาย (เก็บขยะ)

เช่นเดียวกับภาษา Java, Python ใช้อ้างอิงนับเทคนิคง่ายๆนี้เพื่อติดตามวัตถุในหน่วยความจำ

ในการบันทึกภายในหลามของวัตถุทั้งหมดโดยใช้หมายเลขตามลำดับของการอ้างอิง

ตัวแปรสำหรับการติดตามภายในเรียกว่าเคาน์เตอร์อ้างอิง

เมื่อวัตถุที่ถูกสร้างขึ้นจะสร้างจำนวนการอ้างอิงเมื่อวัตถุที่ไม่มีความจำเป็นที่จะกล่าวอ้างอิงถึงการนับวัตถุที่จะกลายเป็น 0 มันคือการเก็บขยะ แต่การกู้คืนไม่ได้ "ทันที" โดยล่ามในเวลาที่เหมาะสมวัตถุขยะครอบครองหน่วยความจำถมพื้นที่

a = 40      # 创建对象  <40>
b = a       # 增加引用, <40> 的计数
c = [b]     # 增加引用.  <40> 的计数

del a       # 减少引用 <40> 的计数
b = 100     # 减少引用 <40> 的计数
c[0] = -1   # 减少引用 <40> 的计数

กลไกการเก็บขยะไม่เพียง แต่สำหรับจำนวนการอ้างอิงวัตถุคือ 0, เดียวกันยังสามารถจัดการกับกรณีของการอ้างอิงแบบวงกลม มันหมายถึงการอ้างอิงแบบวงกลม, วัตถุสองหมายถึงแต่ละอื่น ๆ แต่ไม่มีการอ้างอิงตัวแปรอื่น ๆ ที่พวกเขา ในกรณีนี้จะมีเพียงจำนวนการอ้างอิงไม่เพียงพอ เก็บขยะของงูหลามเป็นจริงมีการอ้างอิงถึงเคาน์เตอร์วงจรและเก็บขยะ ในฐานะที่เป็นคนเก็บขยะอ้างอิงนับเสริมจะให้ความสนใจกับจำนวนที่จัดสรรวัตถุขนาดใหญ่ (และไม่นับผู้ที่ถูกทำลายโดยอ้างอิง) ในกรณีนี้ล่ามจะหยุดความพยายามที่จะทำความสะอาดทุกรอบ unreferenced

ตัวอย่าง

Destructor __del__ __ del__ ถูกเรียกเมื่อวัตถุถูกทำลายเมื่อวัตถุจะไม่ถูกนำมาใช้วิธี __ del__ ที่ทำงาน:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

class Point:
   def __init__( self, x=0, y=0):
      self.x = x
      self.y = y
   def __del__(self):
      class_name = self.__class__.__name__
      print class_name, "销毁"

pt1 = Point()
pt2 = pt1
pt3 = pt1
print id(pt1), id(pt2), id(pt3) # 打印对象的id
del pt1
del pt2
del pt3

ตัวอย่างของผลลัพธ์ข้างต้นมีดังนี้

3083401324 3083401324 3083401324
Point 销毁

หมายเหตุ: โดยปกติแล้วคุณจำเป็นต้องกำหนดระดับในไฟล์ที่แยกจากกัน

มรดกระดับ

หนึ่งในผลประโยชน์ที่สำคัญของการเขียนโปรแกรมเชิงวัตถุจะถูกนำไปใช้ซ้ำนำมาใช้รหัสเพื่อให้บรรลุหนึ่งในจำนวนนี้คือผ่านกลไกมรดก ที่สืบทอดมาชนิดที่เข้าใจอย่างสมบูรณ์และความสัมพันธ์ระหว่างเรียนย่อยลงไป

คำเตือน: มรดกไวยากรณ์คลาสที่ได้รับชื่อชั้น (ชื่อชั้นฐาน): // ... เขียนชื่อชั้นฐานในวงเล็บเมื่อชั้นฐานคือความหมายชั้นในหมู่ tuples ระบุ

ในการทดแทนหลามของบางส่วนของคุณสมบัติที่:

  • 1: ในการกำหนดค่าดังต่อไปนี้ (__init __ () วิธีการ) ระดับ Cheng Zhongji จะไม่ถูกเรียกโดยอัตโนมัติจะต้องใช้เฉพาะที่เรียกว่าคนในตัวสร้างของคลาสที่ได้รับของ
  • 2: เมื่อคุณเรียกวิธีการเรียนฐานที่คุณจะต้องเพิ่มคำนำหน้าชื่อชั้นของชั้นฐานและจำเป็นที่จะต้องนำตัวแปรพารามิเตอร์ตัวเอง ไม่จำเป็นต้องนำพารามิเตอร์ตัวเองแตกต่างจากการเรียกใช้ฟังก์ชันสามัญในชั้นเรียน
  • 3: งูหลามแรกเสมอหาชนิดที่สอดคล้องกันของวิธีการที่ถ้ามันไม่สามารถหาวิธีการที่สอดคล้องกันในชั้นเรียนมาก็เริ่มที่จะมองหนึ่งโดยหนึ่งในชั้นฐาน (วิธีแรกเรียกร้องที่จะพบในชั้นนี้เพียงเพื่อจะพบว่าจะหาชั้นฐาน)

ถ้าคอลัมน์มากกว่าหนึ่งชั้นใน tuple มรดกแล้วมันจะเรียกว่า "มรดกหลาย."

ไวยากรณ์:

ประกาศของชั้นเรียนมาคล้ายกับระดับผู้ปกครองของพวกเขาแล้วสืบทอดรายการชั้นฐานที่มีชื่อระดับดังต่อไปนี้:

class SubClassName (ParentClass1[, ParentClass2, ...]):
   'Optional class documentation string'
   class_suite

ตัวอย่าง:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

class Parent:        # 定义父类
   parentAttr = 100
   def __init__(self):
      print "调用父类构造函数"

   def parentMethod(self):
      print '调用父类方法'

   def setAttr(self, attr):
      Parent.parentAttr = attr

   def getAttr(self):
      print "父类属性 :", Parent.parentAttr

class Child(Parent): # 定义子类
   def __init__(self):
      print "调用子类构造方法"

   def childMethod(self):
      print '调用子类方法 child method'

c = Child()          # 实例化子类
c.childMethod()      # 调用子类的方法
c.parentMethod()     # 调用父类方法
c.setAttr(200)       # 再次调用父类的方法
c.getAttr()          # 再次调用父类的方法

รหัสข้างต้นจะถูกดำเนินการดังต่อไปนี้:

调用子类构造方法
调用子类方法 child method
调用父类方法
父类属性 : 200

คุณสามารถรับช่วงหลายชั้นเรียน

class A:        # 定义类 A
.....

class B:         # 定义类 B
.....

class C(A, B):   # 继承类 A 和 B
.....

คุณสามารถใช้ issubclass () หรือ isinstance () วิธีการในการตรวจสอบ

  • issubclass () - ฟังก์ชั่นบูลีนเพื่อตรวจสอบว่าชั้นเป็น subclass ของชั้นอื่นหรือไวยากรณ์ชั้นลูกหลาน: issubclass (ย่อย SUP)
  • isinstance (obj ชั้น) ฟังก์ชั่นบูลีนถ้า obj เป็นตัวอย่างของการเรียนวัตถุหรือวัตถุเช่นคลาสเป็น subclass ผลตอบแทนจริง

วิธีการแทนที่

หากฟังก์ชั่นที่คุณมีวิธีการเรียนผู้ปกครองไม่สามารถตอบสนองความต้องการของคุณคุณสามารถเขียนวิธีการเรียนผู้ปกครองของคุณในประเภทรอง:

ตัวอย่าง:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

class Parent:        # 定义父类
   def myMethod(self):
      print '调用父类方法'

class Child(Parent): # 定义子类
   def myMethod(self):
      print '调用子类方法'

c = Child()          # 子类实例
c.myMethod()         # 子类调用重写方法

รันโค้ดข้างต้นออกผลมีดังนี้

调用子类方法

วิธีการมูลนิธิมากเกินไป

ตารางต่อไปนี้แสดงบางส่วนของคุณสมบัติทั่วไปที่คุณสามารถแทนที่ในชั้นเรียนของคุณ:

เลขที่ วิธีการอธิบายเพียงโทร &
1 __init__ (ตัวเอง [args ... ] )
เพียงแค่เรียกวิธีสร้าง:obj = className (args)
2 __del __ (ตัวเอง)
destructorsลบวัตถุโทรวิธีการที่ง่าย:Dell obj
3 __repr __ (ตัวเอง)
การแปลงรูปแบบสำหรับล่ามในการอ่านการเรียกวิธีการที่ง่าย:Repr (obj)
4 __str __ (ตัวเอง)
สำหรับค่าลงในรูปแบบที่เหมาะสมสำหรับการอ่านของมนุษย์เรียกวิธีง่ายๆ:STR (obj)
5 __cmp__ (ตัวเอง, x)
วัตถุเรียกวิธีการที่ค่อนข้างง่าย:ซีเอ็มพี (obj, x)

ดำเนินงานมาก

งูใหญ่ยังสนับสนุนการดำเนินงานมากตัวอย่างดังต่อไปนี้:

#!/usr/bin/python

class Vector:
   def __init__(self, a, b):
      self.a = a
      self.b = b

   def __str__(self):
      return 'Vector (%d, %d)' % (self.a, self.b)
   
   def __add__(self,other):
      return Vector(self.a + other.a, self.b + other.b)

v1 = Vector(2,10)
v2 = Vector(5,-2)
print v1 + v2

ผลการดำเนินโค้ดข้างต้นมีดังนี้

Vector(7,8)

แอตทริบิวต์การเรียนและวิธีการ

ระดับทรัพย์สินส่วนตัว

__private_attrs: จุดเริ่มต้นที่สองขีดระบุว่าทรัพย์สินที่มีความเป็นส่วนตัวและไม่สามารถนำมาใช้หรือเข้าถึงได้โดยตรงในชั้นเรียนภายนอก ตนเอง .__ private_attrs เมื่อใช้ในวิธีการเรียน

วิธีการเรียน

ในการตกแต่งภายในบกคำหลักที่ใช้ def สามารถกำหนดเป็นวิธีการเรียนที่มีความหมายทั่วไปของฟังก์ชั่นที่แตกต่างกันวิธีการเรียนต้องมีพารามิเตอร์ตัวเองและเป็นพารามิเตอร์แรก

วิธีการส่วนตัวของชั้น

__private_method: สองขีดแรกวิธีการที่ถูกประกาศเป็นวิธีเอกชนในชั้นเรียนไม่สามารถเรียกภายนอก โทร private_methods ตนเอง .__ ภายในชั้นเรียน

ตัวอย่าง

#!/usr/bin/python
# -*- coding: UTF-8 -*-

class JustCounter:
	__secretCount = 0  # 私有变量
	publicCount = 0    # 公开变量

	def count(self):
		self.__secretCount += 1
		self.publicCount += 1
		print self.__secretCount

counter = JustCounter()
counter.count()
counter.count()
print counter.publicCount
print counter.__secretCount  # 报错,实例不能访问私有变量

งูใหญ่โดยการเปลี่ยนชื่อรวมถึงชื่อของชั้นเรียน:

1
2
2
Traceback (most recent call last):
  File "test.py", line 17, in <module>
    print counter.__secretCount  # 报错,实例不能访问私有变量
AttributeError: JustCounter instance has no attribute '__secretCount'

งูใหญ่ไม่ได้รับอนุญาตเข้าถึงข้อมูลส่วนตัวของชั้น instantiated, แต่คุณสามารถใช้คุณลักษณะการเข้าถึง object._className__attrName รหัสต่อไปนี้จะเข้ามาแทนที่บรรทัดสุดท้ายของโค้ดข้างต้นรหัส:

.........................
print counter._JustCounter__secretCount

รันโค้ดข้างต้นผลการดำเนินการดังต่อไปนี้:

1
2
2
2