欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Python基础编程_6~10_note

程序员文章站 2022-05-23 10:21:59
...

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

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-抽象