0 os模块:一个与操作系统有关的模块


这个模块内容很多,切忌死记硬背,需要使用的时候查询即可

1 sys模块:一个与python解释器有关的模块


使用同上

2 序列化模块

序列化:将其他数据类型转化成字符串类型(一般用于写文件和网络传输中)
反序列化:将字符串类型转化成其他数据类型
序列化模块主要有json模块,pickle模块,shelve模块,接下来将一一讲解:
0)json模块:通用的序列化格式,只有一小部分数据类型可以通过json模块转换成字符串类型,json模块一般有4种方法:dumps();loads();dump();load()
dumps()和loads()的使用:
import json

dic = {'a': '100', 'b': '20'}
lis = json.dumps(dic)
print(lis, type(lis))
dic_ = json.loads(lis)
print(dic_, type(dic_))


dump()和load()的使用:(对文件句柄进行操作)
json.dump()用于将dict类型的数据转成str,并写入到json文件中。
json.load()用于从json文件中读取数据。

import json
dic = {'a': '100', 'b': '20'}
with open('fff.txt', 'w', encoding='utf-8') as f:json.dump(dic, f)

#如果字典中有中文,稍微有所变化

import json
dic = {'a': '中国', 'b': '20'}
with open('fff.txt', 'w', encoding='utf-8') as f:json.dump(dic, f, ensure_ascii=False)

注意:dump和load一次只能处理一个字典,如果需要多次,必须绕过dump和load

import json
l = [{'k1': '111'}, {'k2': '111'}]
f = open('ttt.txt', 'w')
for i in l:str_dic = json.dumps(i)f.write(str_dic + '\n')
f.close()

f = open('ttt.txt')
new_l = []
for line in f:dic = json.loads(line)new_l.append(dic)
f.close()
  1. pickle模块:所有的数据类型都能通过pickle模块转化成字符串数据类型,但是pickle序列化后的内容只有python才能理解,且部分反序列化依赖python代码(这句话目前不能理解)
    pickle模块和json一样,同样提供了dumps();loads();dump();load()方法,但是在使用过程中稍微有所区别
    在dump()的时候必须以‘wb’的方式打开 ,在load()的时候必须以‘rb’的方式打开
import pickle
dic = {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}
str_dic = pickle.dumps(dic)
print(str_dic, type(str_dic))  #一串二进制内容dic2 = pickle.loads(str_dic)
print(dic2, type(dic2))

一个关于dump和load的使用案例:

import pickle
import time
struct_time = time.localtime(1000000000)
print(struct_time)
f = open('pickle_file', 'wb')
pickle.dump(struct_time, f)
f.close()f = open('pickle_file', 'rb')
struct_time2 = pickle.load(f)
print(struct_time2.tm_year)

2) shelve模块:这个模块目前不太成熟,了解即可

3 模块

0)模块的导入
当导入一个模块时,先从sys.modules中看是否被导入,如果没有被导入,就从sys.path路径寻找模块,再创建这个模块的命名空间,把文件中的名字全部放到命名空间上去,这也就是模块不会被重复导入的原因
1)模块的别名
当几个模块执行的功能相同时,可以将这几个模块起同一个别名,这样使用起来就会很方便
2)模块的顺序
导入模块时,要将模块写在程序的最开始,且最好使用
import a
import b
import c
不推荐使用 import a, b, c
顺序一般为:

内置模块

扩展模块

自己写的模块
3)从某个模块中调用某个方法
from a import b
比如:from time import sleep

关于模块的小结:

import 模块名
模块名.方法名 和本文件中的变量名完全不冲突

import 模块名 as 重命名的模块名
#提高代码的兼容性

from 模块名 import 方法名
#直接使用方法名就可以完成操作
#如果本文件中有相同的变量名会发生冲突
#from 模块名 import 变量名 as 重命名的变量名

from 模块名 import 方法名1,方法名2
from 模块名 import *
#将模块中的所有方法名都放到内存中
#如果本文件中有相同的变量名会发生冲突

#import * 和__all__是一对
如果没有__all__, 模块里面的所有方法都被导入
如果有__all__, __all__里有的方法会被导入

在模块中,有一个变量__name__
当我们直接执行这个模块的时候,name == ‘main
当我们在其他模块中引用这个模块的时候,name == ‘模块名

与上文无关,但是关于__name__ == 'main’有点想要补充的
这句话是python程序的入口,相当于c语言中的main函数

4 包

包是一种通过使用‘.模块名’来组织python模块名称空间的方式。
一个完整的python程序通常不只包含一个python文件,一个完整的python程序如下所示:

conf里面放配置文件,让用户可以看懂的
core 核心代码
db 数据
lib 自己写的模块
log 记录的过程
当调用python包时,会自动执行该包下的__init__文件

os.makedirs('glance/api')
os.makedirs('glance/cmd')
os.makedirs('glance/db')
l = []
l.append(open('glance/__init__.py','w'))
l.append(open('glance/api/__init__.py','w'))
l.append(open('glance/api/policy.py','w'))
l.append(open('glance/api/versions.py','w'))
l.append(open('glance/cmd/__init__.py','w'))
l.append(open('glance/cmd/manage.py','w'))
l.append(open('glance/db/models.py','w'))
l.append(open('glance/db/__init__.py','w'))
map(lambda f:f.close() ,l)

#文件内容#policy.py
def get():print('from policy.py')#versions.py
def create_resource(conf):print('from version.py: ',conf)#manage.py
def main():print('from manage.py')#models.py
def register_models(engine):print('from models.py: ',engine)

执行get文件的两种方法:
import glance.api.policy
glance.api.policy.get()
from glance.api.policy import get
get()
如果想调用import glance 然后使用policy versions等功能怎么办呢?
在glance的__init__文件里导入如下模块,利用了自动执行__init__这个功能
from glance import api
from glance import cmd
from glance import db
分别在api,cmd,db的__init__文件里导入如下模块
from glance.api import policy
from glance.api import versions
————————————————
from glance.cmd import manage

————————————————
from glance.db import models

经过尝试
import glance
glance.api.policy.get()
例如:我们在glance/api/version.py中想要导入glance/cmd/manage.py

#在glance/api/version.py#绝对导入
from glance.cmd import manage
manage.main()#相对导入
from ..cmd import manage
manage.main()

5 异常处理

try:ret = int(input('number>>>>>'))print(ret*'*')
except ValueError:print('你的输入有误,请输入一个数字')
except Exception:print('抗压吧务团队1')
else:print('---------')
finally:print('nmsl')

当程序执行遇到错误时,后面的程序就不会执行
#使用try和except就能处理异常
#try是我们需要处理的代码
#except后跟一个错误类型,当代码发生错误且类型相同时,就会执行except的内容
#except 支持多分支(进行一个分支后就不会进入其他分支,在上述程序中,如果发生ValueError,就不会进入Exception)
有没有一个能处理所有错误的类型:Exception
#有了万能的处理机制仍然需要将能预测到的错误单独讨论
#单独处理的内容必须放在万能异常前面
#else:没有异常时会执行else的代码
#finally;不管代码是否异常,都会执行
#finally和return相遇的时候,仍然会执行
#做一些收尾工作

一个简单的程序:

c = []
while True:a = input('请输入数字(退出请输入b):')if a == 'b':breakelse:try:c.append(int(a))except Exception as e:print('你存在如下错误', e)
print(sum(c))
print(len(c))
print(sum(c)/len(c))

6 面向对象三大特性之继承

0)一个类可以被多个类继承
1)一个类可以继承多个负类(多继承),只在python中存在
2)在python3中,所有的类都有其父类,如果没有继承,默认它的父类就是object(顶级类)

class A:passclass B(A):passprint(A.__base__)
print(B.__base__)

.__base__方法可以查询父类

如何更形象地理解继承?

class Animal:def __init__(self, name, hp, aggr):self.name = nameself.hp = hpself.aggr = aggrclass Person(Animal):def __init__(self, name, hp, aggr, sex):Animal.__init__(self, name, hp, aggr)self.sex = sex  # 派生属性self.money = 0  # 派生属性def attack(self, dog):dog.hp -= self.aggrclass Dog(Animal):def __init__(self, name, hp, aggr, kind):Animal.__init__(self, name, hp, aggr)self.kind = kind  # 派生属性def bite(self, person):person.hp -= self.aggrjin = Dog('泰迪', 500, 200, '看家')
alex = Person('陈叔', 999, 111, '男')
print(jin.kind)
print(alex.sex)

小结:
当在自己的类中找不到__init__时,就会到父类里面找__init__
子类中有而父类中没有的属性,叫做派生属性
子类中有而父类中没有的方法, 叫做派生方法
当调用时,先再子类里面找,找不到再在父类里面找
既想实现新的功能,又想调用父类的功能,就需要在子类中调用父类的功能(上述的代码就用了这点,建议好好研究)

一个关于super()的实例:

class A:def hahaha(self):print('A')class B(A):def hahaha(self):super().hahaha()print('B')a = A()
b = B()
b.hahaha()


子类调用父类的方法时,可以使用super() 这种方法可以少传入一个self参数

class Animal:def __init__(self, name, hp, aggr):self.name = nameself.hp = hpself.aggr = aggrclass Person(Animal):def __init__(self, name, hp, aggr, sex):super().__init__(name, hp, aggr)self.sex = sex  # 派生属性self.money = 0  # 派生属性def attack(self, dog):dog.hp -= self.aggrclass Dog(Animal):def __init__(self, name, hp, aggr, kind):super().__init__(name, hp, aggr)self.kind = kind  # 派生属性def bite(self, person):person.hp -= self.aggrjin = Dog('泰迪', 500, 200, '看家')
alex = Person('陈叔', 999, 111, '男')
print(jin.kind)
print(alex.sex)

super()一般都是在类内部使用,如果super要在类外部使用该如何做呢?
Super在类外部使用的时候, super(类名,对象名).(方法)使用

组合和继承的区别:

组合是 “有”的关系
继承是 “是”的关系
多继承(找大爹)
钻石继承

class A:def func(self):print('A')class B(A):def func(self):print('B')class C(A):def func(self):print('C')class D(B, C):def func(self):print('D')d = D()
print(D.mro())


mro()方法可以将继承顺序列出来


Super的本质不是直接找父类,而是根据调用者的节点位置广度优先顺序来判断的

class A:def func(self):print('A')class B(A):def func(self):super().func()print('B')class C(A):def func(self):super().func()print('C')class D(B, C):def func(self):super().func()print('D')d = D()
d.func()

小技巧:

如何在终端上运行点py文件呢?
目前还存在一个疑问:shell和terminal有什么区别????

7 接口类和抽象类

接口类:

from abc import abstractmethod, ABCMetaclass Payment(metaclass=ABCMeta):@abstractmethoddef pay(self, money):passclass Wechat(Payment):def pay(self, money):print("已经使用微信支付了%s元" % money)class Ali(Payment):def pay(self, money):print("已经使用阿里支付了%s元" % money)class Apple(Payment):def pay1(self, money):print("已经使用苹果支付了%s元" % money)def pay(pay_obj, money):  # 接口pay_obj.pay(money)wechat = Wechat()
ali = Ali()
apple = Apple()

上述写法是一种规范:当某个类中没有pay方法时,就会在实例化的时候报错
接口类:支持多继承,但是接口类中的方法都不能实现(不能理解)
抽象类:不支持多继承,但是抽象类中的方法有一些可以实现(不能理解)
abc类是一个抽象类
接口类也存在多继承
接口类和抽象类都不能实例化

java中没有多继承,但是为了实现多继承,可以用interface(接口)来实现

7 面向对象三大特性之多态

多态指的是一类事物有多种形态

from abc import abstractmethod, ABCMetaclass Animal(metaclass=ABCMeta): #同一类事物:动物@abstractmethoddef talk(self):passclass People(Animal): #动物的形态之一:人def talk(self):print('say hello')class Dog(Animal): #动物的形态之二:狗def talk(self):print('say wangwang')class Pig(Animal): #动物的形态之三:猪def talk(self):print('say aoao')peo = People()
dog = Dog()
pig = Pig()#peo、dog、pig都是动物,只要是动物肯定有talk方法
#于是我们可以不用考虑它们三者的具体是什么类型,而直接使用
peo.talk()
dog.talk()
pig.talk()#更进一步,我们可以定义一个统一的接口来使用def func(obj):obj.talk()func(pig)

鸭子类型

Python崇尚鸭子类型,即‘如果看起来像、叫声像而且走起路来像鸭子,那么它就是鸭子。
python程序员通常根据这种行为来编写程序。例如,如果想编写现有对象的自定义版本,可以继承该对象
也可以创建一个外观和行为像,但与它无任何关系的全新对象,后者通常用于保存程序组件的松耦合度(类之间的相关程度)。

关于多态的深入理解:

class Animal(object):def run(self):print('Animal is running...')class Dog(Animal):def run(self):print('Dog is running1...')def eat(self):print('Eating meat...')class Cat(Animal):def run(self):print('Cat is running2...')def eat(self):print('Eating meat...')dog = Dog()
dog.run()cat = Cat()
cat.run()
a = list()  # a是list类型
b = Animal()  # b是Animal类型
c = Dog()   # c是Dog类型def run_twice(animal):animal.run()animal.run()run_twice(cat)class Tortoise(Animal):def run(self):print('Tortoise is running slowly...')run_twice(Tortoise())


你会发现,新增一个Animal的子类,不必对run_twice()做任何修改,实际上,任何依赖Animal作为参数的函数或者方法都可以不加修改地正常运行,原因就在于多态。
多态的好处就是,当我们需要传入Dog、Cat、Tortoise……时,我们只需要接收Animal类型就可以了,因为Dog、Cat、Tortoise……都是Animal类型,然后,按照Animal类型进行操作即可。由于Animal类型有run()方法,因此,传入的任意类型,只要是Animal类或者子类,就会自动调用实际类型的run()方法,这就是多态的意思:
对于一个变量,我们只需要知道它是Animal类型,无需确切地知道它的子类型,就可以放心地调用run()方法,而具体调用的run()方法是作用在Animal、Dog、Cat还是Tortoise对象上,由运行时该对象的确切类型决定,这就是多态真正的威力:调用方只管调用,不管细节,而当我们新增一种Animal的子类时,只要确保run()方法编写正确,不用管原来的代码是如何调用的。这就是著名的“开闭”原则:
对扩展开放:允许新增Animal子类;
对修改封闭:不需要修改依赖Animal类型的run_twice()等函数。

8 面向对象三大特性之封装

class Person:__key = 123  # 私有的静态属性def __init__(self, name, password):self.name = nameself.__password = password  # 私有属性def __get_password(self):return self.__passworddef login(self):self.__get_password()  # 私有方法alex = Person('水月雨', 'blessing2')
print(alex.name)
print(alex._Person__password)


加上双__就会变成私有的,在类外部不能调用

class Room:def __init__(self, name, length, width):self.__name = nameself.__length = lengthself.__width = widthdef area(self):return self.__length * self.__widthdef get_name(self):return self.__namedef set_name(self, newname):if type(newname) is str and newname.isdigit() == False:self.__name = newnamejin = Room('陈叔', 10, 7)
print(jin.area())
jin.set_name('lux')
print(jin.get_name())


经过测试:父类中的私有属性(私有方法)在子类中也不能调用
所以能用到私有(封装)的场景有:
0)隐藏一个属性,不想在外部被调用
1)想要保护一个属性,不想让这个属性被随意改变
2)想保护这个属性,不被子类继承

在类中修改私有属性:

class People:def __init__(self, name):self.__name = name@propertydef name(self):return self.__name + 'sb'@name.setterdef name(self, newname):self.__name = newnametiger = People('泰哥')
print(tiger.name)
tiger.name = '全班'
print(tiger.name)

在类中删除私有属性:

class People:def __init__(self, name):self.__name = name@propertydef name(self):return self.__name@name.deleterdef name(self):print('我爱你')del self.__nametiger = People('泰哥')
print(tiger.name)
del tiger.name
print(tiger.name)

9 类方法

class Goods:__discount = 0.8def __init__(self, name, price):self.name = nameself.__price = price@propertydef price(self):return self.__price * Goods.__discount@classmethod  # 把一个方法变成一个类的方法,这个方法就可以直接被类调用,  不需要任何依托def change_discount(cls, newdiscount):cls.__discount = newdiscountapple = Goods('苹果', 5)
print(apple.price)
Goods.change_discount(0.5)
print(apple.price)

10 静态方法

如果一个函数既和类没有关系,也和对象没有关系,就用staticmethod伪装成静态方法

class Login:def __init__(self, name, password):self.name = nameself.pwd = passwordprint('这把点了')def login(self):pass@staticmethoddef get_info():user = input('请输入用户名:')pwd = input('请输入密码:')Login(user, pwd)Login.get_info()


关于类方法和静态方法的总结:
类方法和静态方法,都是通过类调用的
对象也可以调用类方法和静态方法,不过推荐通过类来调用
类方法有一个默认参数 cls 代表这个类
静态方法没有默认参数, 就和普通函数一样

python学习生涯 day10-16相关推荐

  1. 小猪的Python学习之旅 —— 16.采集拉勾网数据分析Android就业行情

    小猪的Python学习之旅 -- 16.再尝Python数据分析:采集拉勾网数据分析Android就业行情 标签:Python 一句话概括本文: 爬取拉钩Android职位相关数据,利用numpy,p ...

  2. Python学习笔记:16 面向对象编程入门

    文章目录 类和对象 面向对象的过程 定义类 创建和给对象发消息 打印对象 面向对象编程的支柱 经典案例 例子1:定义一个类描述数字时钟,可以显示时/分/秒,可以运转(走字) 例子2:扑克游戏:四个玩家 ...

  3. Python学习笔记day10

    Twsited异步网络框架 twisted是一个用python语言写的事件驱动的网络框架,他支持很多种协议,包括UDP,TCP,TLS和其他应用层协议,比如HTTP,SMTP,NNTM,IRC,XMP ...

  4. Python学习笔记--day10函数入门

    day10 函数入门 初识函数 函数的参数 函数的返回值 1. 初识函数 函数到底是个什么东西? 函数,可以当做是一大堆功能代码的集合. def 函数名():函数内编写代码......函数名() 例如 ...

  5. head first python豆瓣_Head First Python 学习心得(1-6章)

    写在前面: "吾尝终日而思矣,不如须臾之所学也:吾尝跂而望矣,不如登高之博见也.登高而招,臂非加长也,而见者远:顺风而呼,声非加疾也,而闻者彰.假舆马者,非利足也,而致千里:假舟楫者,非能水 ...

  6. python爬大学生就业数据_小猪的Python学习之旅 —— 16.再尝Python数据分析:采集拉勾网数据分析Android就业行情...

    一句话概括本文: 爬取拉钩Android职位相关数据,利用numpy,pandas和matplotlib对招人公司 情况和招聘要求进行数据分析. 引言: 在写完上一篇<浅尝Python数据分析: ...

  7. 小猪的Python学习之旅 —— 16.再尝Python数据分析:采集拉勾网数据分析Android就业行情...

    一句话概括本文: 爬取拉钩Android职位相关数据,利用numpy,pandas和matplotlib对招人公司 情况和招聘要求进行数据分析. 引言: 在写完上一篇<浅尝Python数据分析: ...

  8. 【坚持】Selenium+Python学习记录 DAY10

    2018/05/31-2018/06/1 [官方文档](https://www.jetbrains.com/help/pycharm/set-up-a-git-repository.html) 通过p ...

  9. think python学习笔记(16)

    选择数据结构时还需要考虑运行时间 例如,in运算符对于字典比列表要快,至少当元素的数目很大的时候 但是通常事先不知道哪个实现更快,一种选择是两个都实现,然后看哪个更快,这种方法被称作基准测试. 另一种 ...

最新文章

  1. AdminIII连接linux Postgresql过程中的几个小问题
  2. linux wait函数头文件_手把手教Linux驱动9-等待队列waitq
  3. 路畅安卓最新固件升级_Airpods连接安卓手机音量异常(airpods固件升级)
  4. IDEA 入门:安装使用详解(创建项目/包/类、运行/关闭/导入项目、字体/字号设置、常用快捷键等)
  5. mac wordpress php7,Mac 下基于 wordpress 搭建个人博客系统
  6. java基础—网络编程———聊天窗口的建立
  7. Python 基础 - Day 2 Learning Note - 字符转编码操作
  8. Netty工作笔记0002---Netty的应用场景
  9. 云免等候服务器响应,云服务器响应
  10. 水晶报表2008部署
  11. PostgreSQL 在Ubuntu下如何修改postgres默认密码
  12. 回收站引发ORACLE查询表空间使用缓慢
  13. Java面向对象通讯录程序
  14. 企业微信二维码转成名片
  15. win10电脑开启卓越性能
  16. 使用redis碰到maxmemory
  17. 2018年北京理工大学计算机学院保研夏令营机试A组
  18. 分享DB2 SQL查询性能问题一例
  19. 74道高级Java面试合集:yapidocker安装插件
  20. 把wps当成浏览器使用

热门文章

  1. 【OS笔记 20】经典同步问题——理发师睡觉问题(信号量解决方案)
  2. 《Applied Energy》期刊介绍(SCI 1区)
  3. Android 获取手机IP
  4. 电脑最全快捷键--建议收藏
  5. 揭秘数据可视化工具的研究现状
  6. 适用于射频器件生产厂家的自动化测试软件
  7. 编程从键盘输入一个字符串,统计该字符串中从‘a‘到‘z‘共26个小写字母各自出现的次数, 将结果存入数组中,并输出
  8. php 打开文件方式
  9. 流程图规范(国家、ISO标准)
  10. Web3域名,热潮还是泡沫?