鍍金池/ 教程/ Python/ 類和實例
基礎
itertools
HTTP 服務
hashlib
閉包
文件和目錄
單元測試
使用 @property
標準模塊
陌生的 metaclass
Base64
進程、線程和協程
讀寫二進制文件
匿名函數
輸入和輸出
Click
元組
字符編碼
partial 函數
參考資料
collections
協程
類和實例
Python 之旅
定制類和魔法方法
常用數據類型
繼承和多態(tài)
ThreadLocal
HTTP 協議簡介
Requests 庫的使用
讀寫文本文件
列表
os 模塊
迭代器 (Iterator)
正則表達式
集合
上下文管理器
異常處理
你不知道的 super
定義函數
datetime
資源推薦
字典
slots 魔法
hmac
第三方模塊
進程
類方法和靜態(tài)方法
函數參數
高階函數
函數
re 模塊
高級特性
線程
argparse
生成器
結束語
字符串
map/reduce/filter
函數式編程
Celery
裝飾器

類和實例

類是一個抽象的概念,我們可以把它理解為具有相同屬性方法的一組對象的集合,而實例則是一個具體的對象。我們還是先來看看在 Python 中怎么定義一個類。

這里以動物(Animal)類為例,Python 提供關鍵字 class 來聲明一個類:

class Animal(object):
    pass

其中,Animal 是類名,通常類名的首字母采用大寫(如果有多個單詞,則每個單詞的首字母大寫),后面緊跟著 (object),表示該類是從哪個類繼承而來的,所有類最終都會繼承自 object 類。

類定義好了,接下來我們就可以創(chuàng)建實例了:

>>> animal = Animal()  # 創(chuàng)建一個實例對象
>>> animal
<__main__.Animal at 0x1030a44d0>

我們在創(chuàng)建實例的時候,還可以傳入一些參數,以初始化對象的屬性,為此,我們需要添加一個 __init__ 方法:

class Animal(object):
    def __init__(self, name):
        self.name = name

然后,在創(chuàng)建實例的時候,傳入參數:

>>> animal = Aniaml('dog1')   # 傳入參數 'dog1'
>>> animal.name               # 訪問對象的 name 屬性
'dog1'

我們可以把 __init__ 理解為對象的初始化方法,它的第一個參數永遠是 self,指向創(chuàng)建的實例本身。定義了 __init__ 方法,我們在創(chuàng)建實例的時候,就需要傳入與 __init__ 方法匹配的參數。

接下來,我們再來添加一個方法:

class Animal(object):
    def __init__(self, name):
        self.name = name
    def greet(self):
        print 'Hello, I am %s.' % self.name

我們添加了方法 greet,看看下面的使用:

>>> dog1 = Animal('dog1')
>>> dog1.name
'dog1'
>>> dog1.greet()
Hello, I am dog1.

現在,讓我們做一下總結。我們在 Animal 類定義了兩個方法:__init__greet。__init__ 是 Python 中的特殊方法(special method),它用于對對象進行初始化,類似于 C++ 中的構造函數;greet 是我們自定義的方法。

注意到,我們在上面定義的兩個方法有一個共同點,就是它們的第一個參數都是 self,指向實例本身,也就是說它們是和實例綁定的函數,這也是我們稱它們?yōu)榉椒ǘ皇呛瘮档脑颉?/p>

訪問限制

在某些情況下,我們希望限制用戶訪問對象的屬性或方法,也就是希望它是私有的,對外隱蔽。比如,對于上面的例子,我們希望 name 屬性在外部不能被訪問,我們可以在屬性或方法的名稱前面加上兩個下劃線,即 __,對上面的例子做一點改動:

class Animal(object):
    def __init__(self, name):
        self.__name = name
    def greet(self):
        print 'Hello, I am %s.' % self.__name
>>> dog1 = Animal('dog1')
>>> dog1.__name   # 訪問不了
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-206-7f6730db631e> in <module>()
----> 1 dog1.__name

AttributeError: 'Animal' object has no attribute '__name'
>>> dog1.greet()   # 可以訪問
Hello, I am dog1.

可以看到,加了 ____name 是不能訪問的,而原來的 greet 仍可以正常訪問。

需要注意的是,在 Python 中,以雙下劃線開頭,并且以雙下劃線結尾(即 __xxx__)的變量是特殊變量,特殊變量是可以直接訪問的。所以,不要用 __name__ 這樣的變量名。

另外,如果變量名前面只有一個下劃線 _,表示不要隨意訪問這個變量,雖然它可以直接被訪問。

獲取對象信息

當我們拿到一個對象時,我們往往會考察它的類型和方法等,比如:

>>> a = 123
>>> type(a)
int
>>> b = '123'
>>> type(b)
str

當我們拿到一個類的對象時,我們用什么去考察它呢?回到前面的例子:

class Animal(object):
    def __init__(self, name):
        self.name = name
    def greet(self):
        print 'Hello, I am %s.' % self.name
  • 第 1 招:使用 type

使用 type(obj) 來獲取對象的相應類型:

>>> dog1 = Animal('dog1')
>>> type(dog1)
__main__.Animal
  • 第 2 招:使用 isinstance

使用 isinstance(obj, type) 判斷對象是否為指定的 type 類型的實例:

>>> isinstance(dog1, Animal)
True
  • 第 3 招:使用 hasattr/getattr/setattr

    • 使用 hasattr(obj, attr) 判斷對象是否具有指定屬性/方法;
    • 使用 getattr(obj, attr[, default]) 獲取屬性/方法的值, 要是沒有對應的屬性則返回 default 值(前提是設置了 default),否則會拋出 AttributeError 異常;
    • 使用 setattr(obj, attr, value) 設定該屬性/方法的值,類似于 obj.attr=value;

看下面例子:

>>> hasattr(dog1, 'name')
True
>>> hasattr(dog1, 'x')
False
>>> hasattr(dog1, 'greet')
True
>>> getattr(dog1, 'name')
'dog1'
>>> getattr(dog1, 'greet')
<bound method Animal.greet of <__main__.Animal object at 0x10c3564d0>>
>>> getattr(dog1, 'x')
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-241-42f5b7da1012> in <module>()
----> 1 getattr(dog1, 'x')

AttributeError: 'Animal' object has no attribute 'x'
>>> getattr(dog1, 'x', 'xvalue')
'xvalue'
>>> setattr(dog1, 'age', 12)
>>> dog1.age
12
  • 第 4 招:使用 dir

使用 dir(obj) 可以獲取相應對象的所有屬性和方法名的列表:

>>> dir(dog1)
['__class__',
 '__delattr__',
 '__dict__',
 '__doc__',
 '__format__',
 '__getattribute__',
 '__hash__',
 '__init__',
 '__module__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 '__weakref__',
 'age',
 'greet',
 'name']

小結

  • 類是具有相同屬性方法的一組對象的集合,實例是一個個具體的對象。
  • 方法是與實例綁定的函數。
  • 獲取對象信息可使用下面方法:
    • type(obj):來獲取對象的相應類型;
    • isinstance(obj, type):判斷對象是否為指定的 type 類型的實例;
    • hasattr(obj, attr):判斷對象是否具有指定屬性/方法;
    • getattr(obj, attr[, default]) 獲取屬性/方法的值, 要是沒有對應的屬性則返回 default 值(前提是設置了 default),否則會拋出 AttributeError 異常;
    • setattr(obj, attr, value):設定該屬性/方法的值,類似于 obj.attr=value;
    • dir(obj):可以獲取相應對象的所有屬性和方法名的列表:

參考資料

上一篇:下一篇:hashlib