Python物件導向進階編程-__slots__、定製類,枚舉

來源:互聯網
上載者:User

標籤:實現   如何   nts   使用   style   err   開發人員   font   __call__   

當在類體內定義好各種屬性後,外部是可以隨便添加屬性的,Python中類如何限制執行個體的屬性?

Python內建了很多定製類,諸如__slots__,__str__

 

__slots__

__slots__方法是在類建立時,為執行個體限定屬性的

class Student(object):    __slots__=(‘name‘,‘age‘)    pass>>>s = Student()>>>s.name=‘tom‘>>>s.age=‘age‘>>>s.score=10  #AttributeError: ‘Student‘ object has no attribute ‘score‘

當__slots__已經進行限定時,再去給執行個體綁定沒有限定的屬性,就會報錯。

__slots__範圍僅限當前的類,當父類中有__slots__屬性時,子類中並沒有限制,當子類中定義__slots__時,子類的執行個體限制就是子類本身加上父類的__slots__。

 

__str__和__repr__

如果要把一個類的執行個體變成 str,就需要實現特殊方法__str__():

class Person(object):    def __init__(self, name, gender):        self.name = name        self.gender = gender    def __str__(self):        return ‘(Person: %s, %s)‘ % (self.name, self.gender)

>>>p = Person(‘tom‘,‘male‘)
>>>print(p)
(Person:tom,male)
>>>p #直接列印p __str__不會被調用
<main.Person object at 0x10c941890>

因為 Python 定義了__str__()__repr__()兩種方法,__str__()用於顯示給使用者,而__repr__()用於顯示給開發人員。

有一個偷懶的定義__repr__的方法:

class Person(object):    def __init__(self, name, gender):        self.name = name        self.gender = gender    def __str__(self):        return ‘(Person: %s, %s)‘ % (self.name, self.gender)    __repr__ = __str__

 

__len__

如果一個類表現得像一個list,要擷取有多少個元素,就得用 len() 函數。

要讓 len() 函數工作正常,類必須提供一個特殊方法__len__(),它返回元素的個數。

例如,我們寫一個 Students 類,把名字傳進去:

class Students(object):    def __init__(self, *args):        self.names = args    def __len__(self):        return len(self.names)

>>>s = Student(‘a‘,‘b‘,‘c‘) #只要正確實現了__len__()方法,就可以用len()函數返回Students執行個體的“長度”
>>>print len(s)
3

 

__call__

Python所有的函數都是可調用對象。

一個類執行個體也可以變成一個可調用對象,只需要實現一個特殊方法__call__()

我們把 Person 類變成一個可調用對象:

class Person(object):    def __init__(self, name, sex):        self.name = name        self.sex = sex    def __call__(self, friend):        print(‘My name is %s...‘ % self.name)        print(‘My friend is %s...‘ % friend)

>>>p = Person(‘tom‘,‘boy‘)
>>>p(‘jerry‘) #對執行個體直接調用
My name is tom
My friend is jerry

 

枚舉

定義枚舉引入模組enum,枚舉類繼承的時Enum類

from enum import Enumclass Book(Enum):    a = 1    math = 2    english = 3    linux = 4    c++ = 5

訪問枚舉有很多方法

>>>Book.a<Book.a: 1>>>>Book(1)<Book.a: 1>>>>print(Book.a)Book.a>>>print(Book(1))Book.a>>>Book.a.name‘a‘>>>Book.a.value1

如果枚舉中成員名有重複的話,就會報錯TypeError: Attempted to reuse key: ‘a‘

成員的值時允許重複的,但是訪問時還是第一個成員屬性,Python將重複的第二個成員看做第一個的別名

from enum import Enumclass Book(Enum):    a = 1    b = 1>>>Book.a<Book.a: 1>>>>Book.b  #訪問b也變成了列印a屬性,b被視為a的別名
<Book.a :1>

 

如果限制枚舉沒有重複的話,引入unique模組,unique是一個類裝飾器,用來約束值

from enum import Enum,unique@uniqueclass Book(Enum):    a = 1    b = 1>>>print(Book.a.value)ValueError:dupplicate values found in <enum ‘Book‘>:b -> a

枚舉支援迭代器 

>>>for b in Book:        print(b)Book.a、...

成員值重複時,只能拿到第一個成員,若要不管重複,列出所有的,使用__members__方法

from enum import Enumclass Book(Enum):    a = 1    math = 2    english = 3    linux = 4    c++ = 5for b in Book.__members__.items():    print(b)#以元組形式列印(‘a‘,<Book.a: 1>)、(‘math‘,<Book.math: 2>)、、、

 

Python物件導向進階編程-__slots__、定製類,枚舉

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.