Python基础编程_6~10_note

写给自己看的,忘记的时候可以看

6 抽象

文档化函数

一个给函数添加注释的姿势

def add(x, y):
    '''return the sum of two num'''
    return x + y


print(add.__doc__)
is 与 ==

前者地址和值要完全相等,后者只需要值相等

a = [1, 2, 3]
b = a
print(a == b)
print(a is b)
a.pop()
print(b)
print(hex(id(a)))
print(hex(id(b)))
b = a[:]
print(a is b)
print(hex(id(a)))
print(hex(id(b)))

c = list(a)
print(a == c)
print(a is c)
print(hex(id(a)))
print(hex(id(b)))

我们看一下输出就懂了

True
True
[1, 2]
0x2bee5c1fc88
0x2bee5c1fc88
False
0x2bee5c1fc88
0x2bee5c2b848
True
False
0x2bee5c1fc88
0x2bee5c2b848
关键字参数和收集参数

关键字参数的好处就是不需要记住函数中形参的顺序

def setime(h, m, s='unknown'):
    print('time is: {0} hour,{1} minutes,{2} seconds'.format(h, m, s))


setime(m=20, s=42, h=13)
setime(h=13, m=20)

看一下默认值的效果

time is: 13 hour,20 minutes,42 seconds
time is: 13 hour,20 minutes,unknown seconds

收集参数主要就是* 和 **

用法很简单,要注意几点:*返回元组,**返回字典,且**要定义在*之后

一些新的函数
print(map.__doc__+'\n~~~~~~~~')
print(sum.__doc__+'\n~~~~~~~~')
print(filter.__doc__+'\n')


# etc
def is_odd(n):
    return n % 2 == 1


tmplist = filter(is_odd, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
newlist = list(tmplist)
print(newlist)
print('\n~~~~~~~~')

结果如下

map(func, *iterables) --> map object

Make an iterator that computes the function using arguments from
each of the iterables.  Stops when the shortest iterable is exhausted.
~~~~~~~~
Return the sum of a 'start' value (default: 0) plus an iterable of numbers

When the iterable is empty, return the start value.
This function is intended specifically for use with numeric values and may
reject non-numeric types.
~~~~~~~~
filter(function or None, iterable) --> filter object

Return an iterator yielding those items of iterable for which function(item)
is true. If function is None, return the items that are true.

[1, 3, 5, 7, 9]

~~~~~~~~

7 更加抽象

关键就是对象吧,主要概念就是多态,封装,继承

class

直接记录一下class的一些花招

class Fruit(object):
    __name = 'fruit'  # private
    taste = 'sweet'

    def getname(self):
        print('name is: {0}'.format(self.__name))

    def getaste(self):
        print('taste is: {0}'.format(self.taste))


fruit = Fruit()
print(fruit._Fruit__name)  # 强行调用私有特性,但是import的时候,不会导入_Fruit
fruit.getname()  # 正常通过公有方法调用


class Mango(Fruit):
    taste = 'very sweet'


mango = Mango()
mango.getaste()  # 超类,继承了父类的方法


class Watermelon(Mango, Fruit):
    __name = 'watermelon'


watermelon = Watermelon()
watermelon.getname()  # 私有特性无法覆盖和继承,永远为最高父类
watermelon.getaste()  # 多个超类,继承不同的类,若类有包含关系,选择子类
print(issubclass(Watermelon, Mango))
print(issubclass(Watermelon, Fruit))  # 判断是否为子类
print(isinstance(watermelon, Watermelon))  # 判断是否为该类实例,不推荐这么用,可以用如下方法
print(watermelon.__class__)  # 知道该对象属于哪个类
print(hasattr(Watermelon, 'getaste'))
print(hasattr(Watermelon, '__name'))
print(hasattr(watermelon.getaste, '__call__'))  # 查看是否可以调用这个方法
print(mango.__dict__)  # 实例查看不了
print(Mango.__dict__)  # 查看对象所有特性
setattr(mango, 'taste', 'sour')  # 修改特性,获取的方法是getattr
print(mango.taste)
print(watermelon.taste)  # 父类特性修改后,子类特性不变

配上输出的结果一目了然

fruit
name is: fruit
taste is: very sweet
name is: fruit
taste is: very sweet
True
True
True
<class '__main__.Watermelon'>
True
False
True
{}
{'__doc__': None, 'taste': 'very sweet', '__module__': '__main__'}
sour
very sweet

异常

每个异常都是一些类,常用的的异常类我觉得等以后写了bug查一下就知道了

一个简单的捕获异常的例子,源自书本

class Calculator(object):
    muffled = True

    def calc(self, expr):
        try:
            return eval(expr)
        except ZeroDivisionError:
            if self.muffled:
                print('Division bey zero is illegal')
            else:
                raise


calculator = Calculator()
calculator.calc('10/0')
calculator.muffled = False
calculator.calc('10/0')
calculator.muffled = True
calculator.calc('10/0')

看一下结果就好了,异常不捕获的话会卡死后面

我们可以选择捕获以后不释放错误,就不会卡死如下

class Calculator(object):
    muffled = True

    def calc(self, expr):
        try:
            return eval(expr)
        except (ZeroDivisionError, TypeError) as e:
            if self.muffled:
                print('Division bey zero is illegal')
            else:
                print(e)


calculator = Calculator()
calculator.calc('10/0')
calculator.muffled = False
calculator.calc('10/0')
calculator.muffled = True
calculator.calc('10/0')

多个错误的时候一定记得加(),然后有个常用的finally,自己这里没写,提一下怕自己忘记,是最后百分之百执行的,配合try使用

9 魔法方法、属性和迭代器

这章节的标题很玄乎就是了

__init__

构造__init__其实还挺普遍的,但是有几个坑自己要注意,例子有些就直接用书上的了,自己稍微改了改

class Bird:
    def __init__(self):
        self.hungry = True
        self.name = 'gugu'

    def eat(self):
        if self.hungry:
            print('aaaa')
            self.hungry = False
        else:
            print('No, thanks')


class SongBird(Bird):
    def __init__(self):
        super().__init__()  # 重写构造函数一定要super,不然继承不了父类构造的属性
        self.sound = 'Squawk'
        self.name = 'gugugu'

    def sing(self):
        print(self.sound)

    def getname(self):
        print('name is: {0}'.format(self.name))


sbb = Bird()
sbb.eat()
sb = SongBird()
sb.sing()
sb.eat()
sb.eat()
sb.getname()
__setattr__和__getattr__

主要是为了偷懒,不用写一大堆get或者set了,当然如果是private的特性另当别论了

如果对象没有该特性,则会调用__getattr__,至于__getattr__可以单纯的偷懒了

class Bird:
    def __init__(self):
        self.hungry = True
        self.name = 'gugu'

    def eat(self):
        if self.hungry:
            print('aaaa')
            self.hungry = False
        else:
            print('No, thanks')


class SongBird(Bird):
    def __init__(self):
        super().__init__()  # 重写构造函数一定要super,不然继承不了父类构造的属性
        self.sound = 'Squawk'
        self.name = 'gugugu'

    def sing(self):
        print(self.sound)

    def __setattr__(self, key, value):
        if key == 'beauty':
            self.name = value
        else:
            self.__dict__[key] = value  # 不是beauty也会调用
            print('OK')

    def __getattr__(self, item):
        if item == 'food':
            print('food is none')
        else:
            raise AttributeError


sb = SongBird()  # 4个OK,父类两次,自己本身两次
print(sb.__dict__)
sb.sing()
print(sb.name)
print(sb.food)
sb.name = 'gugugugu'

输出如下

OK
OK
OK
OK
{'hungry': True, 'name': 'gugugu', 'sound': 'Squawk'}
Squawk
gugugu
food is none
None
OK
装饰器

这个树上一笔带过了,我觉得蛮重要的,就搜了一下

链接:https://www.cnblogs.com/whyaza/p/9505205.html

理解装饰器的前提**:1.所有东西都是对象(函数可以当做对象传递) 2.闭包**

闭包的概念:
1)函数嵌套
2)内部函数使用外部函数的变量
3)外部函数的返回值为内部函数

我自己通俗的理解就是,比如有三个函数A,B,C

A函数里面有个加工的方法是B,A加工C之后,C不光保留了自身的方法,还获得了B的方法,大概是这样吧

从网上拉下来两个例子

原型

import time
def showtime(func):
    def wrapper():
        start_time = time.time()
        func()
        end_time = time.time()
        print('spend is {}'.format(end_time - start_time))

    return wrapper

def foo():
    print('foo..')
    time.sleep(3)

foo = showtime(foo)
foo()

语法糖

import time
def showtime(func):
    def wrapper():
        start_time = time.time()
        func()
        end_time = time.time()
        print('spend is {}'.format(end_time - start_time))

    return wrapper

@showtime  #foo = showtime(foo)
def foo():
    print('foo..')
    time.sleep(3)

def doo():
    print('doo..')
    time.sleep(2)

print(foo.__name__)  # wrapper
print(doo.__name__)  # doo

两种的操作其实是一样的

迭代器

举个书上例子好了,以我的水平,暂时知道他(__iter__)配合__next__使用就好

class Fibs:
    def __init__(self):
        self.a = 0
        self.b = 1

    def __next__(self):
        self.a, self.b = self.b, self.b + self.a
        return self.a

    def __iter__(self):
        return self


fibs = Fibs()
for i in fibs:
    if i > 1000:
        print(i)
        break
生成器

一个强大的特性,我自己觉得最不可思议的就是冻结,简单的理解的话,有yield就是生成器

def flatten(nested):
    for sublist in nested:
        for element in sublist:
            yield element


nested = [[1, 2], [2, 4], [5]]
for num in flatten(nested):
    print(num)

print(list(flatten(nested)))

运行完你会发现是一个一个输出的

自带电池

一个看了标题以后完全不知道要学什么的章节

模块

我们先导入自己做的模块,调用一下,用到了sys

>>> import sys
>>> sys.path.append('D:\Study\Python_基础遍程_note')
>>> from 迭代器_生成器 import *
>>> list(flatten(nested))
[1, 2, 2, 4, 5]
>>> 迭代器_生成器.__name__
'迭代器_生成器
>>> __name__
'__main__'
>>> import pprint
>>> pprint.pprint(sys.path)
['',
 'C:\\Users\\xxxx\\AppData\\Local\\Programs\\Python\\Python35\\Lib\\idlelib',
 'C:\\Users\\xxxx\\AppData\\Local\\Programs\\Python\\Python35\\python35.zip',
 'C:\\Users\\xxxx\\AppData\\Local\\Programs\\Python\\Python35\\DLLs',
 'C:\\Users\\xxxx\\AppData\\Local\\Programs\\Python\\Python35\\lib',
 'C:\\Users\\xxxx\\AppData\\Local\\Programs\\Python\\Python35',
 'C:\\Users\\xxxx\\AppData\\Roaming\\Python\\Python35\\site-packages',
 'C:\\Users\\xxxx\\AppData\\Local\\Programs\\Python\\Python35\\lib\\site-packages',
 'D:\\Study\\Python_基础遍程_note']
>>> print(迭代器_生成器.__file__)  # 查看源代码在哪里
D:\Study\Python_基础遍程_note\迭代器_生成器.py

sys 和 os 模块还是挺管用的,下次遇到了一些问题,可以用这两个模块辅助

就先记录到这里
Hexo链接:https://woaixiaoyuyu.github.io/2019/02/28/Python基础编程-6-10-note/#6-抽象

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值