溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

python中類和對象的示例分析

發(fā)布時(shí)間:2021-09-09 16:00:44 來源:億速云 閱讀:150 作者:小新 欄目:開發(fā)技術(shù)

這篇文章主要介紹python中類和對象的示例分析,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!

類和對象

簡單的說,類是對象的藍(lán)圖和模板,而對象是類的實(shí)例。這個(gè)解釋雖然有點(diǎn)像用概念在解釋概念,但是從這句話我們至少可以看出,類是抽象的概念,而對象是具體的東西。在面向?qū)ο缶幊痰氖澜缰校磺薪詾閷ο?,對象都有屬性和行為,每個(gè)對象都是獨(dú)一無二的,而且對象一定屬于某個(gè)類(型)。當(dāng)我們把一大堆擁有共同特征的對象的靜態(tài)特征(屬性)和動態(tài)特征(行為)都抽取出來后,就可以定義出一個(gè)叫做“類”的東西。

python中類和對象的示例分析

定義類

在Python中可以使用class關(guān)鍵字定義類,然后在類中通過之前學(xué)習(xí)過的函數(shù)來定義方法,這樣就可以將對象的動態(tài)特征描述出來,代碼如下所示。

class Student(object):

 # __init__是一個(gè)特殊方法用于在創(chuàng)建對象時(shí)進(jìn)行初始化操作
 # 通過這個(gè)方法我們可以為學(xué)生對象綁定name和age兩個(gè)屬性
 def __init__(self, name, age):
  self.name = name
  self.age = age

 def study(self, course_name):
  print('%s正在學(xué)習(xí)%s.' % (self.name, course_name))

 # PEP 8要求標(biāo)識符的名字用全小寫多個(gè)單詞用下劃線連接
 # 但是很多程序員和公司更傾向于使用駝峰命名法(駝峰標(biāo)識)
 def watch_av(self):
  if self.age < 18:
   print('%s只能觀看《熊出沒》.' % self.name)
  else:
   print('%s正在觀看島國愛情動作片.' % self.name)

說明: 寫在類中的函數(shù),我們通常稱之為(對象的)方法,這些方法就是對象可以接收的消息。

創(chuàng)建和使用對象

當(dāng)我們定義好一個(gè)類之后,可以通過下面的方式來創(chuàng)建對象并給對象發(fā)消息。

def main():
 # 創(chuàng)建學(xué)生對象并指定姓名和年齡
 stu1 = Student('駱昊', 38)
 # 給對象發(fā)study消息
 stu1.study('Python程序設(shè)計(jì)')
 # 給對象發(fā)watch_av消息
 stu1.watch_av()
 stu2 = Student('王大錘', 15)
 stu2.study('思想品德')
 stu2.watch_av()


if __name__ == '__main__':
 main()

訪問可見性問題

對于上面的代碼,有C++、Java、C#等編程經(jīng)驗(yàn)的程序員可能會問,我們給Student對象綁定的name和age屬性到底具有怎樣的訪問權(quán)限(也稱為可見性)。因?yàn)樵诤芏嗝嫦驅(qū)ο缶幊陶Z言中,我們通常會將對象的屬性設(shè)置為私有的(private)或受保護(hù)的(protected),簡單的說就是不允許外界訪問,而對象的方法通常都是公開的(public),因?yàn)楣_的方法就是對象能夠接受的消息。在Python中,屬性和方法的訪問權(quán)限只有兩種,也就是公開的和私有的,如果希望屬性是私有的,在給屬性命名時(shí)可以用兩個(gè)下劃線作為開頭,下面的代碼可以驗(yàn)證這一點(diǎn)。

class Test:

 def __init__(self, foo):
  self.__foo = foo

 def __bar(self):
  print(self.__foo)
  print('__bar')


def main():
 test = Test('hello')
 # AttributeError: 'Test' object has no attribute '__bar'
 test.__bar()
 # AttributeError: 'Test' object has no attribute '__foo'
 print(test.__foo)


if __name__ == "__main__":
 main()

但是,Python并沒有從語法上嚴(yán)格保證私有屬性或方法的私密性,它只是給私有的屬性和方法換了一個(gè)名字來“妨礙”對它們的訪問,事實(shí)上如果你知道更換名字的規(guī)則仍然可以訪問到它們,下面的代碼就可以驗(yàn)證這一點(diǎn)。之所以這樣設(shè)定,可以用這樣一句名言加以解釋,就是“We are all consenting adults here”。因?yàn)榻^大多數(shù)程序員都認(rèn)為開放比封閉要好,而且程序員要自己為自己的行為負(fù)責(zé)。

class Test:

 def __init__(self, foo):
  self.__foo = foo

 def __bar(self):
  print(self.__foo)
  print('__bar')


def main():
 test = Test('hello')
 test._Test__bar()
 print(test._Test__foo)


if __name__ == "__main__":
 main()

在實(shí)際開發(fā)中,我們并不建議將屬性設(shè)置為私有的,因?yàn)檫@會導(dǎo)致子類無法訪問(后面會講到)。所以大多數(shù)Python程序員會遵循一種命名慣例就是讓屬性名以單下劃線開頭來表示屬性是受保護(hù)的,本類之外的代碼在訪問這樣的屬性時(shí)應(yīng)該要保持慎重。這種做法并不是語法上的規(guī)則,單下劃線開頭的屬性和方法外界仍然是可以訪問的,所以更多的時(shí)候它是一種暗示或隱喻

面向?qū)ο蟮闹е?/strong>

面向?qū)ο笥腥笾е悍庋b、繼承和多態(tài)。后面兩個(gè)概念在下一個(gè)章節(jié)中進(jìn)行詳細(xì)的說明,這里我們先說一下什么是封裝。我自己對封裝的理解是“隱藏一切可以隱藏的實(shí)現(xiàn)細(xì)節(jié),只向外界暴露(提供)簡單的編程接口”。我們在類中定義的方法其實(shí)就是把數(shù)據(jù)和對數(shù)據(jù)的操作封裝起來了,在我們創(chuàng)建了對象之后,只需要給對象發(fā)送一個(gè)消息(調(diào)用方法)就可以執(zhí)行方法中的代碼,也就是說我們只需要知道方法的名字和傳入的參數(shù)(方法的外部視圖),而不需要知道方法內(nèi)部的實(shí)現(xiàn)細(xì)節(jié)(方法的內(nèi)部視圖)。

練習(xí)

練習(xí)1:定義一個(gè)類描述數(shù)字時(shí)鐘

class Clock(object):
 """數(shù)字時(shí)鐘"""

 def __init__(self, hour=0, minute=0, second=0):
  """初始化方法

  :param hour: 時(shí)
  :param minute: 分
  :param second: 秒
  """
  self._hour = hour
  self._minute = minute
  self._second = second

 def run(self):
  """走字"""
  self._second += 1
  if self._second == 60:
   self._second = 0
   self._minute += 1
   if self._minute == 60:
    self._minute = 0
    self._hour += 1
    if self._hour == 24:
     self._hour = 0

 def show(self):
  """顯示時(shí)間"""
  return '%02d:%02d:%02d' % \
    (self._hour, self._minute, self._second)


def main():
 clock = Clock(23, 59, 58)
 while True:
  print(clock.show())
  sleep(1)
  clock.run()


if __name__ == '__main__':
 main()

練習(xí)2:定義一個(gè)類描述平面上的點(diǎn)并提供移動點(diǎn)和計(jì)算到另一個(gè)點(diǎn)距離的方法。

from math import sqrt


class Point(object):

 def __init__(self, x=0, y=0):
  """初始化方法
  
  :param x: 橫坐標(biāo)
  :param y: 縱坐標(biāo)
  """
  self.x = x
  self.y = y

 def move_to(self, x, y):
  """移動到指定位置
  
  :param x: 新的橫坐標(biāo)
  "param y: 新的縱坐標(biāo)
  """
  self.x = x
  self.y = y

 def move_by(self, dx, dy):
  """移動指定的增量
  
  :param dx: 橫坐標(biāo)的增量
  "param dy: 縱坐標(biāo)的增量
  """
  self.x += dx
  self.y += dy

 def distance_to(self, other):
  """計(jì)算與另一個(gè)點(diǎn)的距離
  
  :param other: 另一個(gè)點(diǎn)
  """
  dx = self.x - other.x
  dy = self.y - other.y
  return sqrt(dx ** 2 + dy ** 2)

 def __str__(self):
  return '(%s, %s)' % (str(self.x), str(self.y))


def main():
 p1 = Point(3, 5)
 p2 = Point()
 print(p1)
 print(p2)
 p2.move_by(-1, 2)
 print(p2)
 print(p1.distance_to(p2))


if __name__ == '__main__':
 main()

以上是“python中類和對象的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI