1. 程式人生 > >菜鳥學python之類和對象

菜鳥學python之類和對象

類 對象


我們把一類相同的事物叫做類,其中相同事物相同的屬性可以抽象出來,而一些相同的動作行為,也可以抽象成方法。

比如,汽車是一個類,它包括價格、品牌等屬性。那麽我們需要打印某一輛車的價格和品牌,只需要使用一句代碼 print "the car‘s type ‘ford’,price:280000",但是當我們需要對一百個品種的車打印這句話的時候,怎麽辦呢?

這個問題我們通過以前學過的函數式編程就可以實現啦!我們只需要寫一個類,然後將不同的車品牌和價格以參數的方式傳到類裏就好了。這樣大大的提高了代碼的重用性,我們就不需要把同樣的print這句話寫100次了。

class Car:
def __init__(self,type,price):
self.type=type
self.price=price
def printInfo(self):
print(‘the car‘+self.type+‘\‘s price is:‘+str(self.price))
carOne=Car(‘passat‘,25000)
carTwo=Car(‘ford‘,25000000)
carOne.printInfo()
carTwo.printInfo()
the carpassat‘s price is:25000
the carford‘s price is:25000000

想一想,如果沒有這些做法,想要打印信息,那會多麻煩?而創建好類模版後,我們只需要根據具體情況創建不同對象(實例),然後再調用對象內的封裝好的打印函數就好


1.self是個什麽鬼

self是自身對象的引用,也是一個變量。創建不同對象時,self自然指向的對象也就不同;

所以當我們使用passat這個對象去調用printCarInfo這個方法的時候,其實是做了這樣一部操作printCarInfo(passat),把passat這個對象傳給了printCarInfo方法,passat這個對象又包含了兩個屬性cartype、price,我們在python規定這樣使用一個對象中的變量:passat.cartype、passat.price

在對象中,屬性有點類似一個家庭中的物件,而方法相當於是要使用物件的人,人和物件都屬於這個家庭,但是不給人指定具體哪個物件,人還可以使用人家的東西,萬一借來的呢?所以要指定使用自己家的,就要用一個self(指向自家家庭的門牌號)

類的初始化過程:

carOne=Car(‘passat‘,25000)

其實這兩句話每句話都完成了三個功能:

第一,從car類中實例化出了一個對象——passat/ford;

第二:給新對象的屬性賦了值

第三:將引用調給carOne

2 init 初始化函數

由於類可以起到模板的作用,因此,可以在創建實例的時候,把一些我們認為必須綁定的屬性強制填寫進去。通過定義一個特殊的 __init__ 方法,在創建實例的時候,就把 type ,price等屬性綁上去:

註意到 __init__ 方法的第一個參數永遠是 self ,表示創建的實例本身,因此,在 __init__ 方法內部,就可以把各種屬性綁定到 self ,因為 self就指向創建的實例本身。有了 __init__ 方法,在創建實例的時候,就不能傳入空的參數了,必須傳入與 __init__ 方法匹配的參數,但 self 不需要傳,Python 解釋器自己會把實例變量傳進去

3 方法

我們在使用printInfo函數打印數據時,不需要到外部去執行。直接封裝在內部。這樣,就把“數據”給封裝起來了。這些封裝數據的函數是和Car類本身是關聯起來的,我們稱之為類的方法

要定義一個方法,除了第一個參數是 self 外,其他和普通函數一樣。要調用一個方法,只需要在實例變量上直接調用,除了 self 不用傳遞,其他參數正常傳入

def printInfo(self):
print(‘the car‘+self.type+‘\‘s price is:‘+str(self.price))
carOne.printInfo()

這樣一來,我們從外部看 Car 類,就只需要知道,創建實例需要給出 type 和 price ,而如何打印,都是在 Student 類的內部定義的,這些數據和邏輯被“封裝”起來了,調用很容易,但卻不用知道內部實現的細節。

4 訪問限制

從前面 Student 類的定義來看,外部代碼還是可以自由地修改一個實例的 price 、 type 屬性:

carOne.price=250
the carpassat‘s price is:250

1)私有屬性

如果要讓內部屬性不被外部訪問,可以把屬性的名稱前加上兩個下劃線__ ,在 Python 中,實例的變量名如果以 __ 開頭,就變成了一個私有變量(private),只有內部可以訪問,外部不能訪問

class Car:
    def __init__(self,type,price):
        self.__type=type
        self.__price=price
carOne=Car(‘wote‘,20)
 carOne.price
AttributeError: ‘tuple‘ object has no attribute ‘price‘

此時已經不能訪問了,如果想訪問咋辦?

通過內部方法返回值

如果想改變咋辦?

 def get_price(self)
    return self.__price
 def get_type(self)
      return self.__type

通過內部方法傳入值,再賦值給self

  def set_price(self,price)
     self.__price=price
  def set_type(self,type)
     self.__type=type

思考:

原先那種直接通過 carOne.price = 2500 也可以修改啊,為什麽要定義一個方法大費周折?

因為在方法中,可以對參數做檢查,避免傳入無效的參數:

def set_price(self,price)
    if 0<=price<=3000:
     self.__price=price
  else:
        print(‘i cant pay‘)

雙下劃線開頭的實例變量是不是一定不能從外部訪問呢?其實也不是。不能直接訪問 __price 是因為 Python 解釋器對外把 __price 變量改成了_Car__price ,所以,仍然可以通過 _Car__price 來訪問 __price 變量,但最好別這樣幹

實例屬性和類屬性

由於 Python 是動態語言,根據類創建的實例可以任意綁定屬性。給實例綁定屬性的方法是通過實例變量,或者通過 self 變量:

class Student:
def __init__(self, name):
self.name = name
s = Student(‘Bob‘)
s.score = 90

但是,如果 Student 類本身需要綁定一個屬性呢?可以直接在 class 中定義屬性,這種屬性是類屬性,歸 Student 類所有:

class Student:
name = ‘Student‘

當我們定義了一個類屬性後,這個屬性雖然歸類所有,但類的所有實例都可以訪問到。來測試一下:

>>> class Student(object):
... name = ‘Student‘
...
>>> s = Student() # 創建實例 s
>>> print(s.name) # 
Student
>>> print(Student.name) # 打印類的 name 屬性
Student
>>> s.name = ‘Michael‘ # 給實例綁定 name 屬性
>>> print(s.name) # 由於實例屬性優先級比類屬性高,因此,它會屏蔽掉類的name 屬性
Michael
>>> print(Student.name) # 但是類屬性並未消失,用 Student.name 仍然可以訪問
Student
>>> del s.name # 如果刪除實例的 name 屬性
>>> print(s.name) # 再次調用 s.name,由於實例的 name 屬性沒有找到,類的name 屬性就顯示
Student

從上面的例子可以看出,在編寫程序的時候,千萬不要把實例屬性和類屬性使用相同的名字,因為相同名稱的實例屬性將屏蔽掉類屬性,但是當你刪除實例屬性後,再使用相同的名稱,訪問到的將是類屬性。


本文出自 “11818322” 博客,請務必保留此出處http://11828322.blog.51cto.com/11818322/1967264

菜鳥學python之類和對象