期末总结(持续更新)


python笔记

Python的介绍

Python是解释型语言

Python(英国发音:/ˈpaɪθən/ 美国发音:/ˈpaɪθɑːn/),是一种广泛使用的高级编程语言,属于通用型编程语言,由吉多·范罗苏姆创造,第一版发布于1991年。可以视之为一种改良(加入一些其他编程语言的优点,如面向对象)的LISP。作为一种解释型语言,Python的设计哲学强调代码的可读性和简洁的语法(尤其是使用空格缩进划分代码块,而非使用大括号或者关键词)。相比于C++或Java,Python让开发者能够用更少的代码表达想法。不管是小型还是大型程序,该语言都试图让程序的结构清晰明了。 

Life is short you need Python (人生苦短,我用Python)    

Python的用途:
    WEB应用
        Facebook 豆瓣 。。。
    爬虫程序
    科学计算
    自动化运维
    大数据(数据清洗)
    云计算
    桌面软件/游戏
    人工智能
    。。。     

Python开发环境搭建

开发环境搭建就是安装Python的解释器
Python的解释器分类:
    CPython(官方)
        用c语言编写的Python解释器
    PyPy
        用Python语言编写的Python解释器
    IronPython
        用.net编写的Python解释器
    Jython
        用Java编写的Python解释器

步骤:
    1.下载安装包 python-3.6.5.exe
        - 3.x
        - 2.x    
    2.安装(傻瓜式安装) 
    3.打开命令行窗口,输入python 出现如下内容
        Python 3.6.5 (v3.6.5:f59c0932b4, Mar 28 2018, 16:07:46) [MSC v.1900 32 bit (Intel)] on win32
        Type "help", "copyright", "credits" or "license" for more information.
        >>>    

Python的交互界面

当我们通过命令行来输入Python,所进入到的界面就是Python的交互界面
结构:
    版本和版权声明:
    Python 3.6.5 (v3.6.5:f59c0932b4, Mar 28 2018, 16:07:46) [MSC v.1900 32 bit (Intel)] on win32
    Type "help", "copyright", "credits" or "license" for more information.

    命令提示符:
    >>>

    在命令提示符后可以直接输入Python的指令!输入完的指令将会被Python的解释器立即执行!

    安装Python的同时,会自动安装一个Python的开发工具IDLE,通过IDLE也可以进入到交互模式
    但是不同的是,在IDLE中可以通过TAB键来查看语句的提示。
    IDLE实际上就是一个交互界面,但是他可以有一些简单的提示,并且可以将代码保存

交互模式只能你输入一行代码,它就是执行一行,所以他并不适用于我们日常的开发! 
    仅可以用来做一些日常的简单的测试!   

我们一般会将Python代码编写到一个py文件中,然后通过python指令来执行文件中的代码

几个概念

1.表达式
    表达式就是一个类似于数学公式的东西
    比如:10 + 5   8 - 4
    表达式一般仅仅用了计算一些结果,不会对程序产生实质性的影响
    如果在交互模式中输入一个表达式,解释器会自动将表达式的结果输出

2.语句
    在程序中语句一般需要完成某种功能,比如打印信息、获取信息、为变量赋值。。。
    比如:
        print()
        input()
        a = 10
    语句的执行一般会对程序产生一定的影响
    在交互模式中不一定会输出语句的执行结果  

3.程序(program)
    程序就是由一条一条的语句和一条一条的表达式构成的。

4.函数(function)
    函数就是一种语句,函数专门用来完成特定的功能
    函数长的形如:xxx()          
    函数的分类:
        内置函数
            - 由Python解释器提供的函数,可以在Python中直接使用
        自定义函数   
            - 由程序员自主的创建的函数
    当我们需要完成某个功能时,就可以去调用内置函数,或者自定义函数 
    函数的两个要素:
        参数
            - ()中的内容就是函数的参数
            - 函数中可以没有参数,也可以有多个参数,多个参数之间使用,隔开
        返回值        
            - 返回值是函数的返回结果,不是所有的函数都有返回值

基本语法

1.在Python中严格区分大小写
2.Python中的每一行就是一条语句,每条语句以换行结束
3.Python中每一行语句不要过长(规范中建议每行不要超过80个字符)
    "rulers":[80],
4.一条语句可以分多行编写,多行编写时语句后边以\结尾  
5.Python是缩进严格的语言,所以在Python中不要随便写缩进  
6.在Python中使用#来表示注释,#后的内容都属于注释,注释的内容将会被解释器所忽略
    我们可以通过注释来对程序进行解释说明,一定要养成良好的编写注释的习惯
    注释要求简单明了,一般习惯上#后边会跟着一个空格

字面量和变量

字面量就是一个一个的值,比如:1,2,3,4,5,6,‘HELLO’
    字面量所表示的意思就是它的字面的值,在程序中可以直接使用字面量

变量(variable)变量可以用来保存字面量,并且变量中保存的字面量是不定的
    变量本身没有任何意思,它会根据不同的字面量表示不同的意思

一般我们在开发时,很少直接使用字面量,都是将字面量保存到变量中,通过变量来引用字面量

变量和标识符

数据类型

数据类型指的就是变量的值得类型,也就是可以为变量赋哪些值 
数值
    整型
        布尔值
    浮点型
    复数
字符串
空值
在Python数值分成了三种:整数、浮点数(小数)、复数
 在Python中所有的整数都是int类型
 a = 10
 b = 20
Python中的整数的大小没有限制,可以是一个无限大的整数
 c = 999999999999999999999999999999999999999999999 ** 100
 如果数字的长度过大,可以使用下划线作为分隔符
 c = 123_456_789
 d = 0123 10进制的数字不能以0开头
其他进制的整数,只要是数字打印时一定是以十进制的形式显示的
二进制 0b开头
c = 0b10 # 二进制的10
八进制 0o开头
 c = 0o10
十六进制 0x开头
c = 0x10

也可以通过运算符来对数字进行运算,并且可以保证整数运算的精确
c = -100
c = c + 3

浮点数(小数),在Python中所有的小数都是float类型
c = 1.23
c = 4.56

对浮点数进行运算时,可能会得到一个不精确的结果
 c = 0.1 + 0.2 # 0.30000000000000004

print(c)

类型检查

 通过类型检查,可以检查只能值(变量)的类型

a = 123 # 数值
b = '123' # 字符串

 print('a =',a)
 print('b =',b)、
 type()用来检查值的类型
该函数会将检查的结果作为返回值返回,可以通过变量来接收函数的返回值
c = type('123')
c = type(a)
 print(type(b))
print(type(1)) # <class 'int'>
print(type(1.5)) # <class 'float'>
print(type(True)) # <class 'bool'>
print(type('hello'))  # <class 'str'>
print(type(None)) # <class 'NoneType'>

对象(object)

- Python是一门面向对象的语言
- 一切皆对象!
- 程序运行当中,所有的数据都是存储到内存当中然后再运行的!
- 对象就是内存中专门用来存储指定数据的一块区域
- 对象实际上就是一个容器,专门用来存储数据

对象的结构

- 每个对象中都要保存三种数据
    - id(标识)
        > id用来标识对象的唯一性,每一个对象都有唯一的id
        > 对象的id就相当于人的身份证号一样
        > 可以通过id()函数来查看对象的id
        > id是由解析器生成的,在CPython中,id就是对象的内存地址
        > 对象一旦创建,则它的id永远不能再改变

    - type(类型)
        > 类型用来标识当前对象所属的类型
        > 比如:int str float bool 。。。
        > 类型决定了对象有哪些功能
        > 通过type()函数来查看对象的类型
        > Python是一门强类型的语言,对象一旦创建类型便不能修改


    - value(值)
        > 值就是对象中存储的具体的数据
        > 对于有些对象值是可以改变的
        > 对象分成两大类,可变对象 不可变对象
            可变对象的值可以改变
            不可变对象的值不能改变,之前学习的对象都是不可变对象

变量和对象

- 对象并没有直接存储到变量中,在Python中变量更像是给对象起了一个别名
- 变量中存储的不是对象的值,而是对象的id(内存地址),
    当我们使用变量时,实际上就是在通过对象id在查找对象
- 变量中保存的对象,只有在为变量重新赋值时才会改变
- 变量和变量之间是相互独立的,修改一个变量不会影响另一个变量

类型转换

- 所谓的类型转换,将一个类型的对象转换为其他对象
- 类型转换不是改变对象本身的类型,而是根据当前对象的值创建一个新对象
类型转换四个函数 int() float() str() bool()
int() 可以用来将其他的对象转换为整型
# 规则:
#   布尔值:True -> 1   False -> 0
#   浮点数:直接取整,省略小数点后的内容
#   字符串:合法的整数字符串,直接转换为对应的数字
#   如果不是一个合法的整数字符串,则报错 ValueError: invalid literal for int() with base 10: '11.5'
#   对于其他不可转换为整型的对象,直接抛出异常 ValueError
# float() 和 int()基本一致,不同的是它会将对象转换为浮点数
# str() 可以将对象转换为字符串
#  True -> 'True'
#  False -> 'False'
#  123 -> '123' 
#  。。。
#  bool() 可以将对象转换为布尔值,任何对象都可以转换为布尔值
#   规则:对于所有表示空性的对象都会转换为False,其余的转换为True
#  哪些表示的空性:0 、 None 、 '' 。。。

a = True

# 调用int()来将a转换为整型
# int()函数不会对原来的变量产生影响,他是对象转换为指定的类型并将其作为返回值返回
# 如果希望修改原来的变量,则需要对变量进行重新赋值
a = int(a)

a = False
a = int(a)

a = '123'
a = int(a)

a = 11.6
a = int(a)

a = '11.5'
# a = int(a)

a = None
# a = int(a)

a = 1
a = float(a)

a = False
a = float(a)

a = 123
a = str(a)

a = None
a = bool(a)

print('a =',a)
print('a的类型是',type(a))
# b = 456
# print('hello'+str(b))

运算符(操作符)

- 运算符可以对一个值或多个值进行运算或各种操作
- 比如 + 、-、= 都属于运算符
- 运算符的分类:
    1.算术运算符
    2.赋值运算符
    3.比较运算符(关系运算符)
    4.逻辑运算符
    5.条件运算符(三元运算符)
算术运算符
 + 加法运算符(如果是两个字符串之间进行加法运算,则会进行拼串操作)
 - 减法运算符
 * 乘法运算符(如果将字符串和数字相乘,则会对字符串进行复制操作,将字符串重复指定次数)
 / 除法运算符,运算时结果总会返回一个浮点类型
 // 整除,只会保留计算后的整数位,总会返回一个整型
 ** 幂运算,求一个值的几次幂
 % 取模,求两个数相除的余数

 赋值运算符
# = 可以将等号右侧的值赋值给等号左侧的变量
# +=  a += 5 相当于 a = a + 5 
# -=  a -= 5 相当于 a = a - 5 
# *=  a *= 5 相当于 a = a * 5 
# **= a **= 5 相当于 a = a ** 5 
# /=  a /= 5 相当于 a = a / 5 
# //= a //= 5 相当于 a = a // 5 
# %=  a %= 5 相当于 a = a % 5 

关系运算符
# 关系运算符用来比较两个值之间的关系,总会返回一个布尔值
# 如果关系成立,返回True,否则返回False
# > 比较左侧值是否大于右侧值
# >= 比较左侧的值是否大于或等于右侧的值
# < 比较左侧值是否小于右侧值
# <= 比较左侧的值是否小于或等于右侧的值
# == 比较两个对象的值是否相等
# != 比较两个对象的值是否不相等
#   相等和不等比较的是对象的值,而不是id
# is 比较两个对象是否是同一个对象,比较的是对象的id
# is not 比较两个对象是否不是同一个对象,比较的是对象的id

逻辑运算符
# 逻辑运算符主要用来做一些逻辑判断
# not 逻辑非
#   not可以对符号右侧的值进行非运算
#       对于布尔值,非运算会对其进行取反操作,True变False,False变True
#       对于非布尔值,非运算会先将其转换为布尔值,然后再取反
#       
# and 逻辑与
#   and可以对符号两侧的值进行与运算
#    只有在符号两侧的值都为True时,才会返回True,只要有一个False就返回False
#    与运算是找False的
#    Python中的与运算是短路的与,如果第一个值为False,则不再看第二个值
#   
# or 逻辑或
#   or 可以对符号两侧的值进行或运算
#    或运算两个值中只要有一个True,就会返回True
#    或运算是找True的
#    Python中的或运算是短路的或,如果第一个值为True,则不再看第二个值

条件运算符(三元运算符)
# 语法: 语句1 if 条件表达式 else 语句2
# 执行流程:
#   条件运算符在执行时,会先对条件表达式进行求值判断
#       如果判断结果为True,则执行语句1,并返回执行结果
#       如果判断结果为False,则执行语句2,并返回执行结果
Python中使用变量,不需要声明,直接为变量赋值即可
a = 10
不能使用没有进行过赋值的变量
如果使用没有赋值过的变量,会报错 NameError: name 'b' is not defined
 print(b)
Python是一个动态类型的语言,可以为变量赋任意类型的值,也可以任意修改变量的值
a = 'hello'
print(a)

 标识符
在Python中所有可以自主命名的内容都属于标识符
 比如:变量名、函数名、类名
 标识符必须遵循标识符的规范
 1.标识符中可以含有字母、数字、_,但是不能使用数字开头
  例子:a_1 _a1 _1a
  2.标识符不能是Python中的关键字和保留字
    也不建议使用Python中的函数名作为标识符,因为这样会导致函数被覆盖
 3.命名规范:
  在Python中注意遵循两种命名规范   下划线命名法   所有字母小写,单词之间使用_分割  max_length min_length hello_world xxx_yyy_zzz
 帕斯卡命名法(大驼峰命名法) 首字母大写,每个单词开头字母大写,其余字母小            MaxLength MinLength HelloWorld XxxYyyZzz        
如果使用不符合标准的标识符,将会报错 SyntaxError: invalid syntax    

字符串

格式化字符串
a = 'hello'

字符串之间也可以进行加法运算
 如果将两个字符串进行相加,则会自动将两个字符串拼接为一个
a = 'abc' + 'haha' + '哈哈'
 a = 123 
 字符串只能不能和其他的类型进行加法运算,如果做了会出现异常 TypeError: must be str, not int
print("a = "+a) # 这种写法在Python中不常见
a = 123
 print('a =',a)

 在创建字符串时,可以在字符串中指定占位符
 %s 在字符串中表示任意字符
%f 浮点数占位符
%d 整数占位符
b = 'Hello %s'%'孙悟空'
b = 'hello %s 你好 %s'%('tom','孙悟空')
b = 'hello %3.5s'%'abcdefg' # %3.5s字符串的长度限制在3-5之间
b = 'hello %s'%123.456
b = 'hello %.2f'%123.456
b = 'hello %d'%123.95
b = '呵呵'

 print('a = %s'%a)

 格式化字符串,可以通过在字符串前添加一个f来创建一个格式化字符串
 在格式化字符串中可以直接嵌入变量
c = f'hello {a} {b}'

print(f'a = {a}')

 拼串
print('欢迎 '+name+' 光临!')
 多个参数
print('欢迎',name,'光临!')
 占位符
print('欢迎 %s 光临!'%name)
格式化字符串
print(f'欢迎 {name} 光临!')
 字符串的复制(将字符串和数字相乘)
a = 'abc'
* 在语言中表示乘法
如果将字符串和数字相乘,则解释器会将字符串重复指定的次数并返回
a = a * 20
print(a)

布尔值和空值

 布尔值(bool)
 布尔值主要用来做逻辑判断
 布尔值一共有两个 True 和 False
 True表示真 False表示假
a = True
a = False
 print('a =',a)

 布尔值实际上也属于整型,True就相当于1,False就相当于0
 print(1 + False)
 None(空值)
None专门用来表示不存在
b = None
print(b)

条件判断语句(if语句)

语法:if 条件表达式 : 
    代码块
 执行的流程:if语句在执行时,会先对条件表达式进行求值判断,
 如果为True,则执行if后的语句
    如果为False,则不执行
 默认情况下,if语句只会控制紧随其后的那条语句,如果希望if可以控制多条语句,
  则可以在if后跟着一个代码块
代码块
代码块中保存着一组代码,同一个代码块中的代码,要么都执行要么都不执行
 代码块就是一种为代码分组的机制
 如果要编写代码块,语句就不能紧随在:后边,而是要写在下一行
 代码块以缩进开始,直到代码恢复到之前的缩进级别时结束
缩进有两种方式,一种是使用tab键,一种是使用空格(四个)
  Python的官方文档中推荐我们使用空格来缩进
  Python代码中使用的缩进方式必须统一
 "translate_tabs_to_spaces": true,     

input()函数

该函数用来获取用户的输入
input()调用后,程序会立即暂停,等待用户输入
用户输入完内容以后,点击回车程序才会继续向下执行
  用户输入完成以后,其所输入的的内容会以返回值得形式返回
    注意:input()的返回值是一个字符串
  input()函数中可以设置一个字符串作为参数,这个字符串将会作为提示文字显示
 a = input('请输入任意内容:')
print('用户输入的内容是:',a)
 input()也可以用于暂时阻止程序结束

if-else语句

if-else语句
# 语法: 
#   if 条件表达式 :
#       代码块
#   else :
#       代码块
# 执行流程:
#   if-else语句在执行时,先对if后的条件表达式进行求值判断
#       如果为True,则执行if后的代码块
#       如果为False,则执行else后的代码块

if-elif-else语句

if-elif-else语句
# 语法:
#   if 条件表达式 :
#       代码块
#   elif 条件表达式 :
#       代码块
#   elif 条件表达式 :
#       代码块
#   elif 条件表达式 :
#       代码块
#   else :
#       代码块
#       
执行流程:
#   if-elif-else语句在执行时,会自上向下依次对条件表达式进行求值判断,
#       如果表达式的结果为True,则执行当前代码块,然后语句结束
#       如果表达式的结果为False,则继续向下判断,直到找到True为止
#       如果所有的表达式都是False,则执行else后的代码块
#   if-elif-else中只会有一个代码块会执行

循环语句

循环语句
 循环语句可以使指定的代码块重复指定的次数
 循环语句分成两种,while循环 和 for循环
while循环
语法:
#   while 条件表达式 :
#       代码块
#   else :
#       代码块
执行流程:
#   while语句在执行时,会先对while后的条件表达式进行求值判断,
#       如果判断结果为True,则执行循环体(代码块),
#       循环体执行完毕,继续对条件表达式进行求值判断,以此类推,
#       直到判断结果为False,则循环终止,如果循环有对应的else,则执行else后的代码块

条件表达式恒为True的循环语句,称为死循环,它会一直运行,慎用!
# while True :
#     print('hello')

循环的三个要件(表达式)
# 初始化表达式,通过初始化表达式初始化一个变量
# i = 0

 条件表达式,条件表达式用来设置循环执行的条件
# while i < 10 :
#     print(i)
更新表达式,修改初始化变量的值
#     i += 1

break和continue

break
break可以用来立即退出循环语句(包括else)
continue
continue可以用来跳过当次循环
break和continue都是只对离他最近的循环起作用
pass
pass是用来在判断或循环语句中占位的

列表(list)

- 列表是Python中的一个对象
- 对象(object)就是内存中专门用来存储数据的一块区域
- 之前我们学习的对象,像数值,它只能保存一个单一的数据
- 列表中可以保存多个有序的数据
- 列表是用来存储对象的对象
- 列表的使用:
    1.列表的创建
    2.操作列表中的数据

序列(sequence)

- 序列是Python中最基本的一种数据结构
- 数据结构指计算机中数据存储的方式
- 序列用于保存一组有序的数据,所有的数据在序列当中都有一个唯一的位置(索引)
    并且序列中的数据会按照添加的顺序来分配索引
- 序列的分类:
    可变序列(序列中的元素可以改变):
        > 列表(list)
    不可变序列(序列中的元素不能改变):
        > 字符串(str)    
        > 元组(tuple)

可变对象

- 每个对象中都保存了三个数据:
    id(标识)
    type(类型)
    value(值)    

- 列表就是一个可变对象
    a = [1,2,3]

- a[0] = 10 (改对象)
    - 这个操作是在通过变量去修改对象的值
    - 这种操作不会改变变量所指向的对象    
    - 当我们去修改对象时,如果有其他变量也指向了该对象,则修改也会在其他的变量中体现

- a = [4,5,6] (改变量)
    - 这个操作是在给变量重新赋值
    - 这种操作会改变变量所指向的对象
    - 为一个变量重新赋值时,不会影响其他的变量

- 一般只有在为变量赋值时才是修改变量,其余的都是修改对象

字典(dict)

- 字典属于一种新的数据结构,称为映射(mapping)
- 字典的作用和列表类似,都是用来存储对象的容器
- 列表存储数据的性能很好,但是查询数据的性能的很差
- 在字典中每一个元素都有一个唯一的名字,通过这个唯一的名字可以快速的查找到指定的元素
- 在查询元素时,字典的效率是非常快的
- 在字典中可以保存多个对象,每个对象都会有一个唯一的名字
    这个唯一的名字,我们称其为键(key),通过key可以快速的查询value
    这个对象,我们称其为值(value)
    所以字典,我们也称为叫做键值对(key-value)结构
    每个字典中都可以有多个键值对,而每一个键值对我们称其为一项(item)

集合(set)

- 集合和列表非常相似
- 不同点:
    1.集合中只能存储不可变对象
    2.集合中存储的对象是无序(不是按照元素的插入顺序保存)
    3.集合中不能出现重复的元素

异常

程序在运行过程当中,不可避免的会出现一些错误,比如:
    使用了没有赋值过的变量
    使用了不存在的索引
    除0
    ...
这些错误在程序中,我们称其为异常。
程序运行过程中,一旦出现异常将会导致程序立即终止,异常以后的代码全部都不会执行!    

处理异常

程序运行时出现异常,目的并不是让我们的程序直接终止!
Python是希望在出现异常时,我们可以编写代码来对异常进行处理!    

try语句
    try:
        代码块(可能出现错误的语句)
    except 异常类型 as 异常名:
        代码块(出现错误以后的处理方式)
    except 异常类型 as 异常名:
        代码块(出现错误以后的处理方式)
    except 异常类型 as 异常名:
        代码块(出现错误以后的处理方式)
    else:
        代码块(没出错时要执行的语句)    
    finally:
        代码块(该代码块总会执行)    

    try是必须的 else语句有没有都行
    except和finally至少有一个    

可以将可能出错的代码放入到try语句,这样如果代码没有错误,则会正常执行,
    如果出现错误,则会执行expect子句中的代码,这样我们就可以通过代码来处理异常
    避免因为一个异常导致整个程序的终止            

异常的传播(抛出异常)

当在函数中出现异常时,如果在函数中对异常进行了处理,则异常不会再继续传播,
    如果函数中没有对异常进行处理,则异常会继续向函数调用处传播,
    如果函数调用处处理了异常,则不再传播,如果没有处理则继续向调用处传播
    直到传递到全局作用域(主模块)如果依然没有处理,则程序终止,并且显示异常信息

当程序运行过程中出现异常以后,所有的异常信息会被保存一个专门的异常对象中,
    而异常传播时,实际上就是异常对象抛给了调用处
    比如 : ZeroDivisionError类的对象专门用来表示除0的异常
            NameError类的对象专门用来处理变量错误的异常
            ....

在Python为我们提供了多个异常对象            

抛出异常

- 可以使用 raise 语句来抛出异常,
    raise语句后需要跟一个异常类 或 异常的实例

文件(File)

- 通过Python程序来对计算机中的各种文件进行增删改查的操作
- I/O(Input / Output)
- 操作文件的步骤:
    ① 打开文件
    ② 对文件进行各种操作(读、写),然后保存
    ③ 关闭文件

打开文件

open(file, mode='r', buffering=-1, encoding_=None, errors=None, newline=None, closefd=True, opener=None)
# 使用open函数来打开一个文件
# 参数:
#   file 要打开的文件的名字(路径)
# 返回值:
#   返回一个对象,这个对象就代表了当前打开的文件

# 创建一个变量,来保存文件的名字
# 如果目标文件和当前文件在同一级目录下,则直接使用文件名即可
file_name = 'demo.txt'

# 在windows系统使用路径时,可以使用/来代替 \
# 或者可以使用 \\ 来代替 \
# 或者也可以使用原始字符串
file_name = 'hello\\demo.txt'
file_name = r'hello\demo.txt'

# 表示路径,可以使用..来返回一级目录
file_name = '../hello/demo.txt'

# 如果目标文件距离当前文件比较远,此时可以使用绝对路径
# 绝对路径应该从磁盘的根目录开始书写
file_name = r'C:\Users\lilichao\Desktop\hello.txt'

# file_obj = open(file_name) # 打开 file_name 对应的文件

# print(file_obj)

关闭文件

打开文件
file_name = 'demo.txt'

调用open()来打开文件
# file_obj = open(file_name)

 当我们获取了文件对象以后,所有的对文件的操作都应该通过对象来进行
读取文件中的内容
read()方法,用来读取文件中的内容,它会将内容全部保存为一个字符串返回
# content = file_obj.read()

# print(content)

关闭文件
调用close()方法来关闭文件
# file_obj.close()

with ... as 语句
# with open(file_name) as file_obj :
#     # 在with语句中可以直接使用file_obj来做文件操作
#     # 此时这个文件只能在with中使用,一旦with结束则文件会自动close()
#     print(file_obj.read())

文件读取和写入

readline()
    该方法可以用来读取一行内容
    # print(file_obj.readline(),end='')
    # print(file_obj.readline())
    # print(file_obj.readline())

    readlines()
   该方法用于一行一行的读取内容,它会一次性将读取到的内容封装到一个列表中返回
    # r = file_obj.readlines()
    # pprint.pprint(r[0])
    # pprint.pprint(r[1])
    # pprint.pprint(r[2])
    
使用open()打开文件时必须要指定打开文件所要做的操作(读、写、追加)
# 如果不指定操作类型,则默认是 读取文件 , 而读取文件时是不能向文件中写入的
# r 表示只读的
# w 表示是可写的,使用w来写入文件时,如果文件不存在会创建文件,如果文件存在则会截断文件
#   截断文件指删除原来文件中的所有内容
# a 表示追加内容,如果文件不存在会创建文件,如果文件存在则会向文件中追加内容
# x 用来新建文件,如果文件不存在则创建,存在则报错
# + 为操作符增加功能
#   r+ 即可读又可写,文件不存在会报错
#   w+
#   a+
# with open(file_name , 'w' , encoding='utf-8') as file_obj:
# with open(file_name , 'r+' , encoding='utf-8') as file_obj:

write()来向文件中写入内容
    # 如果操作的是一个文本文件的话,则write()需要传递一个字符串作为参数
    # 该方法会可以分多次向文件中写入内容
    # 写入完成以后,该方法会返回写入的字符的个数

文件的其他操作

import os
from pprint import pprint

# os.listdir() 获取指定目录的目录结构
# 需要一个路径作为参数,会获取到该路径下的目录结构,默认路径为 . 当前目录
# 该方法会返回一个列表,目录中的每一个文件(夹)的名字都是列表中的一个元素
r = os.listdir()

# os.getcwd() 获取当前所在的目录
r = os.getcwd()

# os.chdir() 切换当前所在的目录 作用相当于 cd
# os.chdir('c:/')

# r = os.getcwd()

# 创建目录
# os.mkdir("aaa") # 在当前目录下创建一个名字为 aaa 的目录

# 删除目录
# os.rmdir('abc')

# open('aa.txt','w')
# 删除文件
# os.remove('aa.txt')

os.rename('旧名字','新名字') 可以对一个文件进行重命名,也可以用来移动一个文件
# os.rename('aa.txt','bb.txt')
os.rename('bb.txt','c:/users/lilichao/deskt

Zookeeper总结

一 zookeeper概念

1.zookeeper从设计模式角度来理解:是个基于观察者模式设计的分布式服务管理框架,它主要负责存储和管理数据,然后接受观察者的注册,一旦这些数据的状态发生变化,zookeeper就将负责通知已经在zookeeper上注册的那些观察者做出相应的反应
2.应用场景:zookeeper提供的服务包括:统一命名服务,统一配置管理,服务器节点动态上下线,软负载均衡等。

在这里插入图片描述

二 zookeeper特点


 1. zookeeper:一个领导者(leader),多个跟随者(follwer)组成的集群
 2. 集群中只要一半数以上节点存活,zookeeper集群就能正常服务
 3. 全局数据一致:每个server保存一份相同的数据副本,client无论连接到哪个server,数据都是一致的
 4. 更新请求顺序进行,来自同一个client的更新请求按其发送顺序依次执行
 5. 数据更新原子性,一次数据更新要么成功。要么失败
 6. 实时性,在一定时间范围内,client能读到最新数据

三 数据结构

zookeeper数据模型的结构与unix文件系统很类似,总体上可以看作是一棵树,每个节点称作一个ZNode,每一个ZNode默认能够存储1MB的数据,每个ZNode都可以通过其路径唯一标识

zookeeper由多个节点组成,其中有且仅有一个leader,处理所有事务请求;follower及observer统称learner。learner需要同步leader的数据,follower还参与选举及事务决策过程,zk客户端会打散配置件中的serverAddress顺序并随机组成新的list,然后循环按序取一个服务器地址进行连接,直到成功,follower及observer会将事务请求转交给leader处理

四 zookeeper内部原理

4.1  选举机制
    (1)半数机制:集群中半数以上机器存活,集群可用,所以zookeeper适合安装奇数台服务器
    (2)zookeeper虽然在配置文件中并没有指定Master和Slave。但是,zookeeper工作时,是有一个节点为Leader,其他则为Follower,Leader是通过内部的选举机制临时产生的

zookeeper内部是通过维护一个文件系统来实现功能的,简单来说zookeeper=文件系统+监听通知机制,监听通知机制即为zookeeper将文件系统的改变通知给相关客户端

五 数据同步

基本概念
    会话(Session):指zk客户端与zk服务器之间的会话,在zk中,会话是通过客户端和服务器之间的一个TCP长连接来实现的。通过这个长连接,客户端能够使用心跳检测与服务器保持有效的会话,也能向服务器发送请求并接收响应,还可接收服务器的Watcher事件通知。Session的sessionTimeout,是会话超时时间,如果这段时间内,客户端未与服务器发生任何沟通(心跳或请求),服务器端会清除该session数据,客户端的TCP长连接将不可用,这种情况下,客户端需要重新实例化一个Zookeeper对象。
    事务及ZXID:事务是指能够改变Zookeeper服务器状态的操作,一般包括数据节点的创建与删除、数据节点内容更新和客户端会话创建与失效等操作。对于每个事务请求,zk都会为其分配一个全局唯一的事务ID,即ZXID,是一个64位的数字,高32位表示该事务发生的集群选举周期(集群每发生一次leader选举,值加1),低32位表示该事务在当前选择周期内的递增次序(leader每处理一个事务请求,值加1,发生一次leader选择,低32位要清0)。
    事务日志:所有事务操作都是需要记录到日志文件中的,可通过dataLogDir配置文件目录,文件是以写入的第一条事务zxid为后缀,方便后续的定位查找。zk会采取“磁盘空间预分配”的策略,来避免磁盘Seek频率,提升zk服务器对事务请求的影响能力。默认设置下,每次事务日志写入操作都会实时刷入磁盘,也可以设置成非实时(写到内存文件流,定时批量写入磁盘),但那样断电时会带来丢失数据的风险。
    数据快照:数据快照是zk数据存储中另一个非常核心的运行机制。数据快照用来记录zk服务器上某一时刻的全量内存数据内容,并将其写入到指定的磁盘文件中,可通过dataDir配置文件目录。可配置参数snapCount,设置两次快照之间的事务操作个数,zk节点记录完事务日志时,会统计判断是否需要做数据快照(距离上次快照,事务操作次数等于snapCount/2~snapCount中的某个值时,会触发快照生成操作,随机值是为了避免所有节点同时生成快照,导致集群影响缓慢)。
    过半:所谓“过半”是指大于集群机器数量的一半,即大于或等于(n/2+1),此处的“集群机器数量”不包括observer角色节点。leader广播一个事务消息后,当收到半数以上的ack信息时,就认为集群中所有节点都收到了消息,然后leader就不需要再等待剩余节点的ack,直接广播commit消息,提交事务。选举中的投票提议及数据同步时,也是如此,leader不需要等到所有learner节点的反馈,只要收到过半的反馈就可进行下一步操作。
    zk维护的数据:客户端的会话(session)状态及数据节点(dataNode)信息。zk在内存中构造了个DataTree的数据结构,维护着path到dataNode的映射以及dataNode间的树状层级关系。为了提高读取性能,集群中每个服务节点都是将数据全量存储在内存中。可见,zk最适于读多写少且轻量级数据(默认设置下单个dataNode限制为1MB大小)的应用场景。数据仅存储在内存是很不安全的,zk采用事务日志文件及快照文件的方案来落盘数据,保障数据在不丢失的情况下能快速恢复。

Hive总结

hive简介

Hive是基于Hadoop的一个数据仓库工具(离线),可以将结构化的数据文件映射为一张数据库表,并提供类SQL查询功能。
hive数据分析系统(数据仓库,像一个仓库一样,存放着很多数据,而且可以做各种查询、统计和分析,将结果放入新生的表中)
为什么要使用Hive
    1.操作接口采用类SQL语法,提供快速开发的能力。

    2.避免了去写MapReduce,减少开发人员的学习成本。

    3.功能扩展很方便。
Hive的特点
1.可扩展
   Hive可以自由的扩展集群的规模,一般情况下不需要重启服务。
2.延展性
  Hive支持用户自定义函数,用户可以根据自己的需求来实现自己的函数。
3.容错性
  良好的容错性,节点出现问题SQL仍可完成执行。
hive的基本架构
Jobtracker是hadoop1.x中的组件,它的功能相当于:
Resourcemanager+MRAppMaster

TaskTracker 相当于: 
Nodemanager  +  yarnchild

hive 2.0 以后的版本,底层的运算引擎已经不是mr了,而是spark

hive使用方式

1、直接在交互界面输入sql进行交互。

2、sql里可以直接使用java类型。

3、hive中建立数据库后,会在hdfs中出现对象的库名.db的文件夹

4、建表的目的是为了和数据文件进行映射;建立表之后(默认建立在default库中),hive会在hdfs上建立对应的文件夹,文件夹的名字就是表名称;

  4.1、只要hdfs文件夹中有了数据即文件,对应的表中就会有了记录

  4.2、hdfs文件中的数据是按照分隔符进行切分的(value.toString().split("分割符"))(默认分隔符\001:ctrlA--不可见,cat命令下看不见);表的定义是保存在mysql中的。

hive分区与分桶

分区分的是文件夹,分桶分的是文件,分桶其实就是把大表化成了小表
数据分桶的作用:
好处:1.方便抽样。2.提高join查询效率
所谓分区,这是将满足某些条件的记录打包,做个记号,在查询时提高效率,相当于按文件夹对文件进行分类,文件夹名可类比分区字段
分区的目的就是提高查询效率
分桶是相对分区更细粒度的划分

hive常用命令

创建数据库:CREATA DATABASE school;
查看hive中的数据库:SHOW DATABASE;
切换数据库:use  数据库名;
删除数据库:DROP DATABASE IF EXISTS school CASCADE;
hive中默认的行和列分隔符:
     \n:行分隔符
     ^A:列分隔符
     ^B:ARRAY,MAP,STRUCT中元素之间的分隔符
     ^C:MAP中KEY和VALUE之间的分隔符

hive表

内部表:管理数据,创建目录,剪切文件,随着表的删除,表结构,目录和数据文件都删除
内部表控制着数据的生命周期,当内部表删除的时候,目录和其中的文件也会被删除
外部表:共享数据,不创建目录,不操作文件,随着表的删除,只删除表结构,不删除数据文件
在查询操作上,内部表和外部表梦言任何区别
分区字段也是表中的列,叫做虚拟列(虚拟字段),因为他们的值不在数据文件中,需要在导入数据的时候手动添加

hive聚合函数和rank函数

count(*) :计算总行数,包含NULL值的行
sum(col):计算指定行的值和行
avg(col):计算指定行的值的平均值
min(col):计算指定行的最小值
max(col):计算指定行的最大值

  rank函数:rank值相同时,名次会重复,总数不变;
  dense_rank值相同时,名次会重复,总数变少;
  row_number值相同时,名次按照顺序不重复,总数不变;
  partition  by:按照指定字段进行分组,任何组内数据的排名

hive排序和查询

ORDER BY排序,只使用一个reduce,全局有序,但比较慢,默认升序(SAC)也可以指定降序
例如:查询所有学生信息并按照年龄升序排序
         SELECT * FROM student ORDER BY age;
          SELECT * FROM student ORDER BY age ASC;
SORT BY可以使用多个reduce,每个reduce输出的数据有序,全局无序
SORT BY通常搭配DISTRIBUTE BY使用,DISTRIBUTE BY保证列值相同的数据发送到同一个reduce进行处理。

hive查询:
   子查询:子查询是指在一个完整的查询语句中,嵌套若干个不同功能的小查询,从而完成复合查询的编写形式,hive只支持WHERE和FROM子句中的子查询,并且WHERE子查询只支持IN,NOT IN,EXISTE和NOT EXISTS两种情况。

连接查询:
       内连接(inner join)中,只有进行连接的两个表中都存在与连接标准相匹配的数据才会保留下来,on子句指定了两个表间数据进行连接的条件
       左外连接(left  join),join操作符左表中符合条件的所有记录将会被返回,join操作符右边表中如果没有符合on后面连接条件是记录时,那么右边表指定选择的列的值将是null
       右外连接(right outer join (right join))会返回右边表所有符合条件的记录,左表中匹配不上的字段值用null代替

hive合并和切分

split :按照指定分隔符切分字符串 如:select split(text,' ') from doc;
explode :把集合中的每个元素放入单行  如:selext explode(split(text,' ')) from doc;
COLLECT_SET或COLLECT_LIST:把聚合后的某列的多个值拼装为数组,COLLETC_SET会去除数组中重复的元素,而COLLECT_LIST不会
CONCAT_WS:取出字符串数组中每一个元素,按照指定分隔符拼接
CAST:转换数据类型

Hbase笔记

HBase概念特性

HBase是一个数据库----可以提供数据的实时随机读写
Hbase是Google Bigtable的开源实现,是一个高可靠性,高性能,面向列,可伸缩的分布式存储系统,利用HBase技术可在廉价PC Server上搭建起大规模结构化存储集群。
Hbase的目标是存储并处理大型的数据,更具体来说是仅需使用普通的硬件配置,就能够处理由成千上万的行和列所组成的大型数据。

HBase数据库与关系型数据库区别

HBASE与mysql、oralce、db2、sqlserver等关系型数据库不同,它是一个NoSQL数据库(非关系型数据库)。

 - Hbase的表模型与关系型数据库的表模型不同:Hbase的表没有固定的字段定义;Hbase的表中每行存储的都是一些key-value对
 - Hbase的表中有列族的划分,用户可以指定将哪些kv插入哪个列族
 - Hbase的表在物理存储上,是按照列族来分割的,不同列族的数据一定存储在不同的文件中
 - Hbase的表中的每一行都固定有一个行键,而且每一行的行键在表中不能重复
 - Hbase中的数据,包含行键,包含key,包含v
alue,都是byte[]类型,hbase不负责为用户维护数据类型
 - Hbase对事务的支持很差
Hbase相对于其他nosql数据库(mongodb,redis,cassendra,hazelcast)的特点
 - Hbase的表数据存储在HDFS文件系统中
 - HBase具备如下特性:存储容量可以线性扩展;数据存储的安全性可靠性极高

HBase表

 —— hbase表模型中有:行的概念;但没有字段的概念,行中存的都是key-value对,每行中的key-value对中的key可以是各种各样,切分key-value对的数量也可以是各种各样
 —— hbase表模型的要点:
         1.一个表,有表名
         2.一个表可以分为多个列族(不同列族的数据会存储在不同文件中)
         3.表中的每一行有一个"行键rowkey",而且行键在表中不能重复
         4.表中的每一对kv数据称作一个cell
         5.hbase可以对数据存储多个历史版本(历史版本数量可以配置)
         6.整张表由于数据量过大,会被横向切分成若干个region(用rowkey范围标识),不同region的数据也存储在不同文件中
         7.hbase会对插入的数据按顺序存储
 要点一:首先会按行键排序
 要点二:同一行里面的kv会按列族排序,再按k排序
 
 hbase表中只支持byte[]的数据类型,此数据类型包括了:rowkey,key,value,列族名,表名

hbase重要特性–排序特性

插入到hbase中去的数据,hbase会自动排序存储:
排序规则:首先看行键,然后看列族名,然后看列(key);按字典排序
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值