Python基础篇

127 阅读10分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

1.基本语法

1.1类型转换

int()

str()

float()

bool()

1.2 条件判断

if express :

代码块

elif:

代码块

else:

代码块

1.3 循环

while express :

2.列表 元组 字典 集合

2.1 列表 List

my_list = []

2.1.1 切片

[起始位置:结束位置:步长]

2.1.2 列表的方法

append() 插入到最后

insert(x,item)插入到指定位置 第一个参数是位置 第二个参数是要插入的元素

extend(t) 将指定序列添加到当前列表 相当于 +=

clear() 清空列表

pop() 根据索引删除指定元素并返回被删除元素 默认删除最后的一个元素

remove() 根据值删除指定元素,如果列表中有多个相同值的元素,就会删除第一个 无返回值

reverse() 反转列表

sort(reverse=True) 排序 默认升序 传递reverse=True则降序

2.1.3 遍历列表

while

for

2.2 元组 tuple

my_tuple = ()

不可变序列

2.3 字典 dict

my_dict = {}

my_dict = dict(name="zhangsan",age="18")

my_dict = dict([("name","123"),("age","18")])

2.4 集合 set

my_set = {1,2,3,4}

无序 无重复

2.4.1 方法

add() 添加元素

update() 将一个集合中的元素添加到当前集合中

pop() 随机删除一个元素

remove()删除指定元素

clear()清空

copy()浅复制

2.4.2 运算

& 交集

| 并集

----- 差集

^ 亦或集

<= 是否为子集

< 是否是真子集

大于等于

大于 与上面两个相反

3.函数

def

参数

位置参数

根据位置传递参数

关键字参数

根据参数名称传递参数

def hl(a,b,c)

hl(a=1,b=2,c=3) 关键字参数

hl(1,2,3) 位置参数

位置参数可以和关键字参数混合使用

不定长参数

一个*号是元组

两个*号是字典

都只能放在形参的最后一个

def h1(*a): 参数是元组

def h1(**a): 参数是字典

3.2返回值

3.3 文档字符串

函数的说明,编写后可以通过help()查看函数说明

编写方法:

在函数的第一行中写一个字符串就是文档字符串

def h1(a:str,b:bool,c:int):
	"""
	这是一个文档字符串
	"""

3.4 作用域

变量生效的范围

3.4.1 全局作用域

函数以外都是全局作用域

全局作用域中定义的变量就是全局变量

3.4.2 函数作用域

函数内部就是函数作用域

每次调用函数都会产生一个函数作用域

在函数作用域中定义的变量只能在函数内部访问

3.4.3 修改全局变量

使用关键字global

a = 10
def hello():
    #如果要修改全局变量a的值,需要使用global表明
    global a
    a = 20

4.命名空间

保存变量,实质是一个字典

每一个作用域都有一个对应的命名空间

locals() 获取当前作用域的命名空间,在全局中调用获取全局命名空间,在函数内部调用就是函数命名空间

globals() 通过globals()在任意位置获取全局命名空间,函数内部调用此方法获取全局命名空间

5.高阶函数

接受函数作为参数

把函数作为返回值

5.1 匿名函数

语法:

lambda 参数 : 返回值

示例:

fn = lambda a,b : a+b
print(fn(10,20))

常用匿名函数的函数

filter(lambda i : i>1,iterable)

map(lambda i : i+1,iterable)

5.2 闭包

把函数作为返回值返回,通过调用内部函数来操作函数作用域中的变量,减少全局变量的误操作

def out():
	nums = []
	def inner(num):
		nums.append(num)
		return sum(nums)/len(nums)
	return inner
inner = out()
print(inner(1))
print(inner(2))

5.3 装饰器

通过装饰器可以对函数进行包装

def decoration(old):
	def new_function(*args, **kwargs):
		print("装饰器开始")
		result = old(*args,**kwargs)
		print("装饰器结束")
		return result
	return new_function

def fn():
	print("hhh")


new_fn = decoration(fn)

new_fn()

@decoration
def fn1():
	print("1123")

fn1()

装饰器可以是多个,多个@装饰器函数名

最靠近被装饰函数的装饰器先生效,远离被装饰函数的后生效

6. 面向对象

6.1. 对象

万物皆对象

对象是内存中用来存放数据的区域

由三部分组成

  1. id
  1. type
  1. value

6.2 类

对象是类的实例

语法:

class 类名:

class MyClass:
    pass
#创建对象
mc = MyClass()

#检查一个对象是否是一个类的实例
isinstance(mc,MyClass)

6.3 使用类创建对象的流程

1.创建变量 对象名

2.给类分配内存

3.把内存id指向赋值给变量

6.4 类中的方法 self

在类中定义方法时都必须定义一个默认形参

class MyClass:
	name = "哈哈哈"
	def say_hello(self):
		print("hello,%s" %self.name)



class1 = MyClass()
class1.say_hello()

此处的self 就是解析器默认传递的参数,这个参数的意义是哪个对象实例调用这个方法,这个参数就是谁

此处的self指向的就是class1

原因是,在say_hello中并不能直接获取到类中的属性,所以只能通过MyClass的对象实例class1来获取对应的属性

6.5 类中的特殊方法(魔术方法)

在类中可以定义一些特殊的方法(魔术方法) 以__(双下划线)开始 以双下划线结束

6.5.1 init

class MyClass:
	name = "哈哈哈"
	def __init__(self,name):
		self.name = name
	def say_hello(self):
		print("hello,%s" %self.name)



class1 = MyClass('zy')
class1.say_hello()

通过init方法可以对类进行初始化赋值

当我们初始化一个对象时,就相当于直接调用init方法,init方法的self可以不用传递,从第二个参数开始传递

7.面向对象的三大特性

7.1 封装

对类中的属性进行隐藏

使用get/set方法来对属性进行赋值/获取操作

__修饰的属性 不能直接读写,实质上是修改成了 下划线类名双下划线属性名

一般情况使用_属性名来标识不想被修改的属性

7.1.1 property装饰器

装饰器的概念见上文

get方法的装饰器

方法名需要跟属性名一致

property装饰器将一个get方法转换为类的属性,当使用property装饰器后,就可以像使用类的属性一样使用方法

class MyClass:
	
	def __init__(self,name):
		self._name = name

	@property
	def name(self):
		return self._name
		

c1 = MyClass("hahah")
print(c1.name)

set方法的装饰器

方法名需要跟属性名一致

@name.setter

class MyClass:
	
	def __init__(self,name):
		self._name = name

	@property
	def name(self):
		return self._name
		
	@name.setter
	def name(self,name):
		self._name = name


c1 = MyClass("hahah")
print(c1.name)
c1.name = "heiehei"
print(c1.name)

setter装饰器依赖getter装饰器

7.2 继承

定义类的时候指定父类

issubclass(a,b) 检查a是不是b的子类

class Person(object):
	'''
		定义人的类
	'''	
	
	def __init__(self):
		pass
	
	def eat(self):
		print("我吃饭")

class  BlackPerson(Person):
	'''
		定义黑人的类 继承黑人
	'''
	def __init__(self):
		pass

	def run(self):
		print("黑人跑得快")

b1 = BlackPerson()

b1.run()
b1.eat()


#检查BlackPerson是否是Person的子类
r = issubclass(BlackPerson,Person)
print(r)

7.2.1 重写 override

当继承了父类的时候,可以对父类的方法进行重新实现 这就是重写

class Person(object):
	'''
		定义人的类
	'''	
	
	def __init__(self):
		pass
	
	def eat(self):
		print("我吃饭")

class  BlackPerson(Person):
	'''
		定义黑人的类 继承黑人
	'''
	def __init__(self):
		pass

	def eat(self):
		print("黑人吃的多")

b1 = BlackPerson()

#调用的是BlackPerson中的eat方法
b1.eat()

7.2.2 super()

当一个类继承父类时,会继承父类的所有方法,包括父类的魔术方法(init等方法),也就是说如果父类在init方法中对类的属性进行了初始化操作时,在子类实例化对象时,也要传入实例化参数,否则报错

使用super()获取当前类的父类

7.2.3 多重继承

#可以使用__bases__获取类的所有父类


class Person(object):
   '''
   	定义人的类
   '''	
   
   def __init__(self):
   	pass
   
   def eat(self):
   	print("我吃饭")

class  BlackPerson(Person):
   '''
   	定义黑人的类 继承黑人
   '''
   def __init__(self):
   	pass

   def eat(self):
   	print("黑人吃的多")



print(BlackPerson.__bases__)

python支持多重继承.,一个子类可以有多个父类,前面的父类的方法会覆盖后面的父类的方法

class  BlackPerson(Person,Animal):
	'''
		定义黑人的类 继承黑人
	'''
	def __init__(self):
		pass

	def eat(self):
		print("黑人吃的多")

开发中尽量避免使用多重继承

7.3 多态

8.方法的区分

class A:
	#实例方法
	def f1(self):
		pass

	#类方法
	@classmethod
	def f2(cls):
		pass

	#静态方法
	@staticmethod
	def f3():
		pass

8.1 实例方法

类中直接定义的方法,定义时需要定义self参数 此参数意义是实例对象

实例可以直接调用 类不能直接调用,类调用的时候需要传递self

8.2 类方法

类中使用@classmethod修饰的方法,定义时需要定义cls参数,此参数意义是类对象

类和实例都可以直接调用

8.3 静态方法

类中使用@staticmethod修饰的方法 定义时可以不要任何参数

类和实例都可以直接调用

9.垃圾回收

python有自动垃圾回收机制,不需要手动回收

#类中可以使用__del__方法看类的回收过程

10.特殊方法

上面的init,del都是特殊方法,不需要手动调用

docs.python.org/3.8/referen… 3.8版本的特殊方法文档

11.数据库

11.1 mysql

连接mysql 需要先下载pymysql模块

pip install pymsql

pip install --upgrade pip 更新pip程序

11.1.1 api

connect(host,port,user,password,db,charset) 建议使用关键字参数

import pymysql

#连接数据库
conn = pymysql.connect(
		host="192.168.164.134"
		,port=3306
		,user="root"
		,password="zhangyao"
		,db="user"
	)

print("连接", conn)

#获取游标 对数据库的操作都是通过游标完成
cursor = conn.cursor()

print("游标", cursor)

#sql
sql = "select * from user"

#获取查询sql的返回条数
resultNum = cursor.execute(sql)

print(resultNum)

#获取查询sql的执行结果
#	fetchall()获取所有的执行结果
#	fetchone()获取一条结果,可以连续使用,使用一次游标往后推一次
rows = cursor.fetchall()
print(rows)

#关闭游标和连接
cursor.close()
conn.close()

12. 模块

使用模块化把程序分解到多个文件中,便于复用开发

一个py文件就是一个模块

模块名规范:字母数字下划线 不能以下划线开头

引入模块规范:

import 模块名  #模块名就是py文件的名称
import 模块名 as 别名 #可以给模块起一个别名
#可以通过__name__获取到模块的名称
print(别名.__name__)
#__name__是__mian__的模块是主模块,主模块只能有一个

同一模块引入多次,只会生效一次

12.1 包 package

包也是模块

当模块代码过多时,使用包分解为多个模块

包==文件夹

普通模块==py文件

引入包与引入模块一样

包中需要有一个init的文件,包含了包的主要信息

引入包中某个模块

#引入包中的某个模块
from 包名 import 模块名
#__pycache__是模块的缓存文件
#缓存的是模块的编译后的文件 二进制机器码

12.2 python 标准库

docs.python.org/3.8/py-modi…

12.2.1 sys模块

操作python解析器的模块

import sys

import sys
#引入pprint
import pprint

#argv 获取命令行参数 返回一个列表
# print(sys.argv)

#modules 获取当前程序的所有模块 返回一个字典
# print(sys.modules)
#美化输出
# pprint.pprint(sys.modules)


#path 返回模块的搜索路径 返回列表
# pprint.pprint(sys.path)

#platform 返回python运行的平台
# pprint.pprint(sys.platform)

#exit() 退出程序
# sys.exit("结束程序")

12.2.2 pprint模块

对print输出的信息进行美化

import pprint

pprint.pprit(sys.modules)

12.2.3 os模块

operating system 用于操作系统的模块

import os

# print(os)

# 获取操作系统的环境变量 返回的是列表
# print(os.environ['path'])

# system() 执行操作系统的指令
os.system("dir")

13. 异常

语法:

try:
    #可能出现错误的代码块
except:
    #出错之后的执行代码
else:
    #没出错执行的代码

13.1 异常传播

如果函数中出现了异常,并且没有对异常进行处理,那么异常就会像外传播,谁调用谁报错,一层一层向外传播,直到传播到有异常处理的地方或者到全局作用域为止

异常传播其实就是把异常对象抛出到调用处

13.2 异常对象

docs.python.org/3.8/library…

Exception 是所有异常的父类

try:
	print(10/0)
#	except可以写多个
except ZeroDivisionError as ze:
	print("除数不能为0")
#	可以在except后增加异常的类型,并对异常起一个别名
except Exception as e:
	print("触发异常",e)
else:
	print("无异常时触发")
#无论是否触发异常,最终都会执行
finally:
	print("无论是否触发异常,最终都会执行")

except finally至少有一个

13.3 自定义异常

关键字 raise

使用raise 抛出异常

语法:

raise 异常类/异常实例

class MyException(Exception):
	def __init__(self, message):
		self._message = message

try:
	a = 9
	if a < 10 :
		raise MyException("不能小于10")
except Exception as e:
	print(e)
finally:
	pass

14.文件

14.1 打开文件

open(文件的路径) 打开文件

文件的路径可以使用相对路径/绝对路径

14.2 关闭文件

file = open("demo.txt")
print(file)

file.close()

直接调用file.close()方法进行文件的关闭

with open("demo.txt") as file:
	print(file)
	file.close()

14.3 文件读取

read()读取文件的所有内容

#使用read读取文件内容
with open("demo.txt") as file:
	content = file.read()
	print(content)

当读取的文件内有中文时,需要指定open的encoding参数

#使用read读取文件内容
with open("demo2.txt",encoding="utf-8") as file:
	content = file.read()
	print(content)

14.3.1 读取大文件

#读取大文件,每次读取100个字符串
with open("demo.txt") as file:
	while True:
		#read()可以传入一个读取字符串的数量
		content = file.read(100)
		#如果读取的内容为空,则说明读取完了,跳出循环
		if not content:
			break
		print(content,end="")

14.3.2 读取行

readline() 读取行

readlines() 读取所有的行,把每一行返回,包装成一个list

14.3.3 读取二进制文件

模式 + b

b 表示打开二进制文件

t表示打开文本文件

14.3.4 tell() seek()

tell()方法告诉当前读取到的位置

seek() 修改当前读取到的位置

seek()有两个参数

  1. 参数1 传入要修改的读取位置
  1. 参数2 传入位置的计算方式
    1. 有三个值
      1. 0 默认值 从开始计算
      2. 1 从当前读取的位置开始计算
      1. 2 从结尾计算 (往前算应传负数)

seek()方法在读取中文文件时需要注意,因为一个中文字符是三个字节,如果seek()修改的读取位置刚好是一个字的某一个字节,那么就会报错

14.4 文件写入

write()

#写入文件,也需要先打开文件,并指定对文件的操作类型
# mode如果不指定,默认是r 读取文件   
	# 有三种格式  r 读取 w 写入 a追加
	# 这三种模式还有增强 
	# r+ 在读取的基础上增加写入
	# w+ 在写入的基础上增加读取
	# a+ 在追加的基础上增加读取
#encoding 指定打开文件的格式是utf8
#需要注意的是 当模式为r时如果文件不存在会报错,当模式为a和w 时,文件不存在会创建文件
with open("demo1.txt",mode="a",encoding="utf-8") as file:

	#write方法会返回写入的字符串的长度
	# write()方法是覆盖写
	# write()方法只能传入字符串,如果想要写入数字也需要转为字符串再传入
	r = file.write("123")
	print(r)

14.5 文件其他操作

借助os模块来对文件进行操作

docs.python.org/3.8/library…

mkdir() 创建文件夹

rmdir() 删除文件夹

chdir() 相当于cd

getcwd() 获取当前所在路径

remove() 删除文件

rename() 重命名/剪切