轻松玩转AI(从Python开始之高级编程和异步IO并发编程)

轻松玩转AI路径:

  1.   从Python开始 [链接]
  2.  数据科学 [链接]
  3.  机器学习 [链接]
  4.  深度学习——神经网络 [链接]

从Python开始


Python3高级编程和异步IO并发编程 目录:


一、python中一切皆对象

1.python中一切皆是对象

1)动态语言

2)函数和类也是对象,属于python的一等公民。

  • 赋值给一个变量
  • 可以添加到集合对象中
  • 可以作为参数传递给函数
  • 可以当做函数的返回值
# 赋值给一个变量

def ask(name='MJ'):
    print(name)

my_func = ask
my_func('MJ')    # 返回:MJ

class Person:
    def __init__(self):
        print('MJ1')

my_class = Person
my_class()
# 返回:MJ1


# 可以添加到集合对象中
# 可以作为参数传递给函数

obj_list = []
obj_list.append(ask)
obj_list.append(Person)
for item in obj_list:
    print(item)
# 返回:
#   MJ
#   None
#   MJ1
#   <__main__.Person object at ...>


# 可以当做函数的返回值

def decorator_func():
    print('dec start')
    return ask

my_ask = decorator_func()
my_ask('tom')
# 返回:
#   dec start
#   tom

2. type、class和object的关系

tpye与class和object关系

a = 1
b = 'abc'

# type -> int/str -> 1

type(1)    # <class 'int'>
type(int)  # <class 'type'>
type(b)    # <class 'str'>
type(str)  # <class 'type'>


# type -> class -> object

class Student():
    pass

stu = Student()
type(stu)      # <class '__main__.Student'>
type(Student)  # <class 'type'>

a = [1, 2]
type(a)     # <class 'list'>
type(list)  # <class 'type'>


# object 是最顶层基类

Student.__bases__    # <class 'object'>  # 基类就是 object

class MyStudent(Student):
    pass

Student.__bases__   # <class '__main__.Student'>


# type 也是一个类,同时也是一个对象
type.__bases__    # <class 'object'>
type(object)      # <class 'type'>
object.__bases__  # ()

3. python中的常见内置类型

1)对象的三个特征:

  • 身份 —— id()
  • 类型 —— tpye()

2)None(None对象全局只有一个)

3)数值:

  • int
  • float
  • complex
  • bool

4)迭代类型

5)序列类型:

  • list
  • bytes、bytearray、memoryview (二进制序列)
  • range
  • tuple
  • str
  • array

6)映射(dict)

7)集合:

  • set
  • frozenset

8)上下文管理类型(with)

9)其他:

  • 模块类型
  • class和实例
  • 函数类型
  • 方法类型
  • 代码类型
  • object类型
  • type类型
  • ellipsis类型 (省略号)
  • notimplemented类型

二、魔法函数

  • 函数名以 双下划线开头和结尾 的函数。
class Company(object):
    def __init__(self, employee_list):
        self.employee = employee_list 

company = Company(['tom', 'bob', 'jane'])

emploee = company.employee
for em in emploee:
    print(em)

等同于:

class Company(object):
    def __init__(self, employee_list):
        self.employee = employee_list 

    def __getitem__(self, item):
        return self.employee[item]

company = Company(['tom', 'bob', 'jane'])

for em in company:
    print(em)

1. python的数据模型以及数据模型对python的影响

  • 魔法函数并非继承object,而是独立存在的。
  • 实现一个特定魔法函数之后,操作就会变得简单。
  • 魔法函数会直接影响到python语法本身,会影响python的内置函数调用。
class Company(object):
    def __init__(self, employee_list):
        self.employee = employee_list 

    def __getitem__(self, item):
        return self.employee[item]

company = Company(['tom', 'bob', 'jane'])

company1 = company[:2]

print(len(company))
class Company(object):
    def __init__(self, employee_list):
        self.employee = employee_list 

    def __len__(self):
        return len(self.employee)

company = Company(['tom', 'bob', 'jane'])

print(len(company))

2. 魔法函数一览

1)非数学运算

(1)字符串表示:

__repr__
__str__
class Company(object):
    def __init__(self, employee_list):
        self.employee = employee_list 

    def __str__(self):
        return ','.join(self.employee)

company = Company(['tom', 'bob', 'jane'])
company   # 隐含调用 __repr__
# 返回:<__main__.Company at ...>

print(company)  # 自动调用 __str__
# 返回:'tom','bob','jane'

(2)集合、序列相关:

__len__
__getitem__
__setitem__
__delitem__
__contains__

(3)迭代相关:

__iter__
__next__

(4)可调用:

__call__

(5)with 上下文管理器:

__enter__
__exit__

(6)数值转换:

__abs__
__bool__
__int__
__float__
__hash__
__index__

(7)元类相关:

__new__
__init__

(8)属性相关:

__getattr__、__setattr__
__getattribute__、__setattribute__
__dir__

(9)属性描述符:

__get__、__set__、__delete__

(10)协程:

__await__、__aiter__、__anext__、
__aenter__、__aexit__

2)数学运算

(1)一元运算符:

__neg__(-)、__pos__(+)、__abs__

(2)二元运算符:

__lt__ (<)、 __le__ (<=) 、
__eq__ (==) 、 __ne__ (!=) 、
__gt__ (>) 、 __ge__ (>=)

(3)算术运算符:

__add__ (+) 、 __sub__ (-) 、
__mul__ (*) 、 __truediv__ (/) 、
__floordiv__ (//) 、 __mod__ (%) 、 
__divmod__ divmod() 、 
__pow__ (**) 或 pow() 、 __round__ round()

(4)反向算术运算符:

__radd__ 、 __rsub__ 、 __rmul__ 、 
__rtruediv__ 、 __rfloordiv__ 、 
__rmod__ 、 __rdivmod__ 、 __rpow__

(5)增量赋值算术运算符:

__iadd__ 、 __isub__ 、 __imul__ 、 
__itruediv__ 、 __ifloordiv__ 、 
__imod__ 、 __ipow__

(6)位运算符:

__invert__ (~)、 __and__ (&) 、 
__or__ (|) 、 __xor__ (^)、 
__lshift__ (<<) 、 __rshift__ (>>)

(7)反向位运算符:

__rlshift__ 、 __rrshift__ 、 
__rand__ 、 __rxor__ 、 __ror__

(8)增量赋值位运算符:

__ilshift__ 、 __irshift__ 、 
__iand__ 、 __ixor__ 、 __ior__

三、深入类和对象

1. 鸭子类型和多态

  • 当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。
  • 所有的类或对象都实现了一个共同的方法,方法名要一样,这些类可以归为同一种类型,这样就可以同时调用这些类的方法。
# 鸭子类型
class Cat(object):
    def say(self):
        print('i an a cat')

class Dog(object):
    def say(self):
        print('i an a dog')

class Duck(object):
    def say(self):
        print('i an a duck')

# animal 可以赋值为 Cat、Dog、Duck,这就是多态。
animal_list = [Cat, Dog, Duck]
for animal in animal_list:
    animal().say()
class Company(object):
    def __init__(self, employee_list):
        self.employee = employee_list 
    def __getitem__(self, item):
        return self.employee[item]
company = Company(['tom', 'bob', 'jane'])

a = ['MJ1', 'MJ2']
b = ['MJ2', 'MJ1']
name_tuple = ('MJ3', 'MJ4')
name_set = set()
name_set.add('MJ5')
name_set.add('MJ6')

# extend 只要是可迭代类型即可
# 会调用 对象 里面的迭代器(隐式调用):__iter__ , __getitem__
a.extend(b)              # 返回:['MJ1', 'MJ2', 'MJ2', 'MJ1']
#a.extend(name_tuple)    # 返回:['MJ1', 'MJ2', 'MJ3', 'MJ4']
#a.extend(name_set)      # 返回:['MJ1', 'MJ2', 'MJ5', 'MJ6']
#a.extend(company)       # 返回:['MJ1', 'MJ2', 'tom', 'bob', 'jane']
print(a)

2. 抽象基类(abc模块)

  • 抽象基类不能实例化。
# 检查某个类是否有某种方法

class Company(object):
    def __init__(self, employee_list):
        self.employee = employee_list

    def __len__(self):
        return len(self.employee)

com = Company(['MJ1', 'MJ2'])
print(len(com))    # 返回:2

# 可判断某类是否有某属性
print(hasattr(com, '__len__'))    # 返回:True

# 可判断类是否有某种类型
# 我们在某些情况之下希望判定某个对象的类型
from collections.abc import Sized
isinstance(com, Sized)    # 返回:True

# 我们需要强制某个子类必须实现某些方法
# 如:实现了一个web框架,集合cache(如希望可替换成 redis, cache, memorychache 之一)
# 则需要设计一个抽象基类,指定子类必须实现某些方法
# 如何去模拟一个抽象基类:
class CacheBase():
    def get(self, key):
        raise NotImplementedError
    def set(set, key, value):
        raise NotImplementedError

class RedisCache(CacheBase):
    pass

redis_cache = RedisCache()
# 调用时会抛出异常
redis_cache.set('key', 'value')

# 如果我们希望初始化时就抛出异常:
import abc
class CacheBase(metaclss=abc.ABCMeta):
    @abc.abstractmethod
    def get(self, key)
        pass

    @abc.abstractmethod
    def set(set, key, value):
        raise NotImplementedError

class RedisCache(CacheBase):
    pass

# 初始化时会抛出异常
redis_cache = RedisCache()

注:不建议使用抽象基类,建议使用 isinstance

3. isinstance和type的区别

  • 使用 isinstance 而不是 type
class A:
    pass

class B(A):
    pass

b = B()
print(isinstance(b, B))    # 返回:True
print(isinstance(b, A))    # 返回:True

print(type(b))       # 返回:<class '__main__.B'>
print(type(b) is B)  # 返回:True
# type 无法找出继承关系
print(type(b) is A)  # 返回:False

4. 类变量和对象变量

class A:
    aa = 1    # 类变量
    def __init__(self, x, y):  # self是类的实例
        # self.x 和 self.y 的 x 和 y 属于 self(即对象变量的值),而不是类。
        self.x = x
        self.y = y

a = A(2, 3)  # 实例就是对象。实例变量就是对象变量。
print(a.x, a.y, a.aa)  # 返回:2  3  1
print(A.aa)            # 返回:1
print(A.x, A.y)        # 会抛出异常

A.aa = 11
print(a.x, a.y, a.aa)  # 返回:2  3  11
print(A.aa)            # 返回:11

a.aa = 11
print(a.x, a.y, a.aa)  # 返回:2  3  100
print(A.aa)            # 返回:11

5. 类属性和实例属性以及查找顺序

  • 由下而上
  • 属性查找顺序按 C3算法
class A:
    name = 'A'

a = A()
print(a.name)  # 返回:A
class A:
    name = 'A'
    def __init__(self):
        self.name = 'obj'

a = A()
print(a.name)  # 返回:obj

C3算法

# 新式类,默认继承 object
class D:
    pass
class C(D):
    pass
class B(D):
    pass
class A(B, C):
    pass

# 查看查找顺序
print(A.__mro__)
# (<class '__main__.A'>,<class '__main__.B'>,<class '__main__.C'>,<class '__main__.D'>,<class '__main__.object'>)
# 新式类,默认继承 object
class D:
    pass
class E:
    pass
class C(E):
    pass
class B(D):
    pass
class A(B, C):
    pass

# 查看查找顺序
print(A.__mro__)
# (<class '__main__.A'>,<class '__main__.B'>,<class '__main__.D'>,<class '__main__.C'>,<class '__main__.E'>,<class '__main__.object'>)

6. 静态方法、类方法、对象方法以及参数

# 实例方法(self)
class Date:
    # 构造函数
    def __init__(self, year, month, day):
        self.year = year
        self.month = month
        self.day = day

    def tomorrow(self):
        self.day += 1

    def __str__(self):
        return '{year}/{month}/{day}'.format(year=self.year, month=self.month, day=self.day)

if __name__ == '__main__':
    new_day = Date(2018, 12, 31)
    new_day.tomorrow()  # python会自动转换 tomorrow(new_day) 调用
    print(new_day)    # 返回:2018/12/32

    #2018-12-31
    date_str = '2018-12-31'
    year, month, day = tuple(date_str.split('-'))
    new_day = Date(int(year), int(month), int(day))
    print(new_day)    # 返回:2018/12/31

使用静态方法优化:

class Date:
    def __init__(self, year, month, day):
        self.year = year
        self.month = month
        self.day = day

    def tomorrow(self):
        self.day += 1

    # 静态方法
    @staticmethod
    def parse_from_string(date_str):
        year, month, day = tuple(date_str.split('-'))
        return Date(int(year), int(month), int(day))

    def __str__(self):
        return '{year}/{month}/{day}'.format(year=self.year, month=self.month, day=self.day)

if __name__ == '__main__':
    new_day = Date(2018, 12, 31)
    new_day.tomorrow()
    print(new_day)    # 返回:2018/12/32

    #2018-12-31
    # 用 staticmethod 完成初始化
    date_str = '2018-12-31'
    new_day = Date.parse_from_string(date_str)
    print(new_day)    # 返回:2018/12/31

静态方法缺点:更改类名时需要更改静态方法返回对象

使用类方法优化:

class Date:
    def __init__(self, year, month, day):
        self.year = year
        self.month = month
        self.day = day

    def tomorrow(self):
        self.day += 1

    # 类方法
    @classmethod
    def from_string(cls, date_str)  # cls 是类本身
        year, month, day = tuple(date_str.split('-'))
        return cls(int(year), int(month), int(day))

    @staticmethod
    def valid_str(date_str):  # 判断日期是否合规
        year, month, day = tuple(date_str.split('-'))
        if int(year)>0 and (int(month)>0 and int(month<=12) and (int(day)>0 and int(day)<=31):
            return True
        return False

    def __str__(self):
        return '{
  year}/{
  month}/{
  day}'.format(year=self.year, month=self.month, day=self.day)

if __name__ == '__main__':
    new_day = Date(2018, 12, 31)
    new_day.tomorrow()
    print(new_day)    # 返回:2018/12/32

    #2018-12-31
    # 用 classmethod 完成初始化
    date_str = '2018-12-31'
    new_day = Date.from_string(date_str)
    print(new_day)    # 返回:2018/12/31

    print(Date.valid_str('2018-12-32'))  # 返回:False

7. 数据封装和私有属性

import Date
class User:
    def __init__(self, birthday):
        # 双下滑线开头 __ 为私有属性
        self.__birthday = birthday

    def get_age(self):
        return 2018 - self.__birthday.year

if __name__ == '__main__':
    user = User(Date(1990,2,1))
    print(user.get_age()) 

    # 会报错,私有属性不允许类外部访问
    print(user.__birthday)
    # 非要访问,可使用:
    print(user._User__birthday)

8. python对象的自省机制

  • 自省是通过一定的机制查询到对象的内部结构
import Date  # 上述 7 的内容
class Person:
    name = 'user'

class Student(Person):
    def __init__(self, school_name):
        self.scool_name = school_name

if __name__ == '__main__':
    user = Student('mooc')

    # 通过 __dict__ 查询属性
    print(user.__dict__)  # 返回:{'scool_name':'mooc'}
    print(user.name)  # 返回:user
    #print(Person.__dict__)
    user.__dict__['school_addr'] = '北京市'
    print(user.school_addr)    # 返回:北京市
    print(dir(user))

9. super函数

为什么要调用super?

from threading import Thread
class MyThread(Thread):
    def __init__(self, name, user):
        self.user = user
        super().__init__(name=name)  # 可使用多线程父类的name属性

super执行顺序不是调用父类,而是按MRO算法调用

class A:
    def __init__(self):
        print('A')

class B:
    def __init__(self):
        print('B')
        super().__init__()

class C(A):
    def __init__(self):
        print('C')
        super().__init__()

class D(B, C):
    def __init__(self):
        print('D')
        super(D, self).__init__()

if __name__ == '__main__':
    print(D.__mro__)
# 返回:(<class '__main__.D'>,<class '__main__.B'>,<class '__main__.C'>,<class '__main__.A'>,<class 'object'>)
    d = D()
# 返回:
#   D
#   B
#   C
#   A

10. 对多继承mixin模式

  • mixin模式特点:
    • mixin类功能单一
    • 不和基类关联,可以和任意基类组合,基类可以不和mixin关联就能初始化成功
    • 在mixin不要使用super用法

11. 上下文管理器with语句

def exe_try():
    try:
        print('code started')
        raise KeyError
        return 1
    except KeyError as e:
        print('key error')
        return 2
    else:
        print('other error')
        return 3
    finally:
        print('finally')
        return 4

if __name__ == '__main__':
    result = exe.try()
    print(result)
# finally 有 return 则直接返回,无则返回上一个的 return 2
# 返回:
#   code started
#   key error
#   finally
#   4
# 上下文管理器协议
class Sample():
    def __enter__(self):
      
  • 7
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值