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-抽象
上一篇: python编程基础1