python高级编程(二)

  1. __ call__ 函数
    该函数定义类的对象被调用时的相关操作。
class MyClass:
    def __call__(self):
        print('You can call cls() directly.')

cls = MyClass()
cls()
# 使用callable() 函数判断对象是否可以直接被调用
print(callable(cls))
print(callable(max))
print(callable([1, 2, 3]))
print(callable(None))
print(callable('str'))

  1. Enum 函数
    enum函数接收两个参数,第一个为枚举类型的名称(字符串类型),第二个是集合类型,里面列出所有的需要枚举的内容。
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() 函数
    python是一门动态语言,在类的创建上是在编译时完成的,所以我们可以动态的为类添加属性和方法。
    type()函数接收三个参数,第一个是类的名称(字符串类型),第二个是所要继承的类(元组),第三个是字典。
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 __ () 函数

new先被调用,init后被调用,new的返回值(实例)将传递给init方法的第一个参数,然后init给这个实例设置一些参数。将类比作制造商,new方法就是前期的原材料购买环节,init方法就是在有原材料的基础上,加工,初始化商品环节.

实例:

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方法,实际等价于append。
    pass

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

输出结果:

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

new() 函数包含四个参数,MetaClass 一般都要继承type类,返回值也是固定的格式,中间值自定义类生成对象的方法。在这个过程中可以,动态为类添加方法和属性。参数attrs 维护一个哈希表,可以通过这个方法为类添加属性和方法。更多用途可以参考文末链接。

  1. traceback 异常的使用
import traceback

try:
    # r = 10 / 0
    r = 10 / 1
except ZeroDivisionError as e:
    print(e)
    r = 1
else:
    print('没有异常')
finally:
    print('不管有没有异常都执行')
print(r)

  1. __ str __
    相当于java当中的tostring( )函数。
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('测试前准备')

    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__
通过对象的索引调用 __ getitem__ 函数

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])

【参考资料】:

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。