python高級編程(二)

  1. __ call__ 函數(shù)
    該函數(shù)定義類的對象被調(diào)用時(shí)的相關(guān)操作。
class MyClass:
    def __call__(self):
        print('You can call cls() directly.')

cls = MyClass()
cls()
# 使用callable() 函數(shù)判斷對象是否可以直接被調(diào)用
print(callable(cls))
print(callable(max))
print(callable([1, 2, 3]))
print(callable(None))
print(callable('str'))

  1. Enum 函數(shù)
    enum函數(shù)接收兩個(gè)參數(shù),第一個(gè)為枚舉類型的名稱(字符串類型),第二個(gè)是集合類型,里面列出所有的需要枚舉的內(nèi)容。
from enum import Enum

Month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr'))
for name, member in Month.__members__.items():
    print(name, '=>', member, ',', member.value)

jan = Month.Jan
print(jan)
  1. 使用type() 函數(shù)
    python是一門動(dòng)態(tài)語言,在類的創(chuàng)建上是在編譯時(shí)完成的,所以我們可以動(dòng)態(tài)的為類添加屬性和方法。
    type()函數(shù)接收三個(gè)參數(shù),第一個(gè)是類的名稱(字符串類型),第二個(gè)是所要繼承的類(元組),第三個(gè)是字典。
def init(self, name):
    self.name = name

def say_hello(self):
    print('Hello, %s!' % self.name)

# Hello = type('Hello', (object, ), dict(__init__ = init, hello = say_hello))
Hello = type('Hello', (object, ), {'__init__':init, 'hello':say_hello})
'''
class Hello:
    def __init__(...)
    def hello(...)
'''
h = Hello('Tom')
h.hello()
  1. __ new __ () 函數(shù)

new先被調(diào)用,init后被調(diào)用,new的返回值(實(shí)例)將傳遞給init方法的第一個(gè)參數(shù),然后init給這個(gè)實(shí)例設(shè)置一些參數(shù)。將類比作制造商,new方法就是前期的原材料購買環(huán)節(jié),init方法就是在有原材料的基礎(chǔ)上,加工,初始化商品環(huán)節(jié).

實(shí)例:

def add(self, value):
    self.append(value)

class ListMetaclass(type):
    def __new__(cls, name, bases, attrs):
         print(cls)
         print(name)
         print(bases)
         print(type(attrs))
        # attrs['add'] = lambda self, value: self.append(value)
        attrs['add'] = add
        attrs['name'] = 'Tom'
        return type.__new__(cls, name, bases, attrs)
        
class MyList(list, metaclass = ListMetaclass):  # 額外增加add方法,實(shí)際等價(jià)于append。
    pass

mli = MyList()
mli.add(1)
mli.add(2)
mli.add(3)
print(mli.name)
print(mli)

輸出結(jié)果:

<class '__main__.ListMetaclass'>
MyList
(<class 'list'>,)
<class 'dict'>
Tom
[1, 2, 3]

new() 函數(shù)包含四個(gè)參數(shù),MetaClass 一般都要繼承type類,返回值也是固定的格式,中間值自定義類生成對象的方法。在這個(gè)過程中可以,動(dòng)態(tài)為類添加方法和屬性。參數(shù)attrs 維護(hù)一個(gè)哈希表,可以通過這個(gè)方法為類添加屬性和方法。更多用途可以參考文末鏈接。

  1. traceback 異常的使用
import traceback

try:
    # r = 10 / 0
    r = 10 / 1
except ZeroDivisionError as e:
    print(e)
    r = 1
else:
    print('沒有異常')
finally:
    print('不管有沒有異常都執(zhí)行')
print(r)

  1. __ str __
    相當(dāng)于java當(dāng)中的tostring( )函數(shù)。
class MyClass:
    def __init__(self, name):
        self.name = name

    def __str__(self):
        print('print will call __str__ first.')
        return 'Hello ' + self.name + '!'

print(MyClass('Tom'))
  1. 單元測試
import unittest

class MyDict(dict):
    pass

class TestMyDict(unittest.TestCase):
    def setUp(self):
        print('測試前準(zhǔn)備')

    def tearDown(self):
        print('測試后清理')

    def test_init(self):
        md = MyDict(one = 1, two = 2)
        self.assertEqual(md['one'], 1)
        self.assertEqual(md['two'], 2)
        # self.assertEqual(md['two'], 3)

    def test_nothing(self):
        pass

if __name__ == '__main__':
    unittest.main()

# python test_module.py
# python -m unittest test_module
# python -m unittest test_module.test_class
# python -m unittest test_module.test_class.test_method

8 __ getitem__
通過對象的索引調(diào)用 __ getitem__ 函數(shù)

class Fib:
    def __getitem__(self, n):
        # print(type(n))
        a, b = 1, 1
        for i in range(n):
            a, b = b, a + b
        return a

f = Fib()
print(f[1])
print(f[5])
print(f[10])

【參考資料】:

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容