不可变类型:数字、字符、元组(一旦改变,变量所指向的地址发生变化)
可变类型:列表、字典、集合(在地址块内部进行修改,变量指向的地址不发生变化)
def fun02(fun):
weight = 100
def fun03():
if weight >= 100:
print("穿件黑色衣服,不要紧身的")
fun()
return fun03
@fun02 #将下面的函数名当做参数传递到fun02函数
def fun001():
print("fun001")
fun001()
sum = lambda a, b: a + b
print(sum(2, 3))
def add(a,b,c):
print(a,b,c)
return a+b+c
plus=partial(add,8)
print(plus(9,10))
print(int("1010",base=2))//表示“1010” 2进制 转换为 十进制
def clean01(times):
print("打扫房间%d次"%times)
def clean02(times):
print("扫地%d次" %times)
def clean_control(times,func):#控制器
return func(times)
clean_control(3,clean02)
1. 如果模块是被导入,__name__的值为模块名字
2. 如果模块是被直接执行,__name__的值为’__main__’
同样的运算符执行不同数据之间的运算时,采用不同的计算方式
运算符的重载案例:
print(1+2)
print("1"+"2")
class Person(object):
def __init__(self,num):
self.num = num
#运算符重载
def __add__(self, other):
return Person(self.num+other.num)
def __str__(self):
return "num="+str(self.num)
per1 = Person(1)
per2 = Person(2)
print(per1+per2)#3 ====print(per1.add(per2))
print(per1.add(per2))
print(per1)
print(per2)
使用@property实现getter 和 setter方法的功能
property:可以让你对受限制访问的属性使用点语法
class Money:
def __init__(self):
self.__money = 0
@property
def money(self):
return self.__money
@money.setter
def money(self, value):
if isinstance(value, int):
self.__money = value
else:
print("error....")
a = Money()
print(a.money)
a.money = 189
print(a.money)
其中在空类中定义:slots=(“name”,“age”,“speak”)等时,在动态添加属性、方法时,定义的属性名、方法名要和上面限制一样才可添加,否则报
序列:包含列表、元组、字符串
序列的主要特点:支持索引和切片
可变数据类型:列表、字典、集合
不可变数据类型:数字、字符串、元组
有序数据类型:字符串、列表、元组
无序数据类型:数字、字典、集合
#有序的数据类型,每增加一个数据,这个数据都会被排到最后
#无序的数据类型,增加一个数据,这个数据不一定会排在最后
字符
字符 功能
. 匹配任意1个字符(除\n)
[] 匹配[]中列举的字符
\d 匹配数字(0~9)
\D 匹配非数字,即不是数字
\s 匹配空白 空格 tab
\S 匹配非空白
\w 匹配单词字符,a~z A~Z 0~9 _ 汉字
\W 匹配非单词字符
字符 功能
* 表示匹配前一个字符出现0次或者无限次,即可有可无
+ 表示匹配前一个字符出现1次或者无限次,即至少一次
? 表示匹配前一个字符出现1次或则0次,
即,要么一次,要么没有
{m} 表示匹配前一个字符出现m次
{m,} 表示前一个字符至少出现m次
{m,n} 表示匹配字符出现从m到n次
字符 功能
^ 匹配字符串的开头
$ 匹配字符串的结尾
\b 表示匹配一个单词的边界
字符 功能
| 匹配左右任意一个表达式
(ab) 将括号中字符作为分组
\num 引用分组num匹配到字符串
正则函数
re.match
尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回""()None。
re.search
匹配成功re.search方法返回一个匹配的对象,否则返回None。
re.match与re.search的区别:
re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None,而re.search匹配整个字符串,直到找到一个匹配。
import re
pattern = re.compile(r'\d+')
m = pattern.match('one12twothree34four')
print(m)
re.compile
用于编译正则表达式,生成一个正则表达式( Pattern )对象,供 match() 和 search() 这两个函数使用。
re.findall (返回空列表)
在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表。
re.finditer(返回迭代器)
和 findall 类似,在字符串中找到正则表达式所匹配的所有子串,并把它们作为一个迭代器返回。
re.split(可扩展)
split 方法按照能够匹配的子串将字符串分割后返回列表,
检索与替换(删除)
语法:
re.sub(pattern, repl, string, count=0, flags=0)
参数:
pattern : 正则中的模式字符串。
repl : 替换的字符串,也可为一个函数。
string : 要被查找替换的原始字符串。
count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配
正则表达式对象
re.RegexObject
re.compile() 返回 RegexObject 对象。
re.MatchObject
group() 返回被 RE 匹配的字符串。
start() 返回匹配开始的位置
end() 返回匹配结束的位置
span() 返回一个元组包含匹配 (开始,结束) 的位置
字符串中必须含有每个()中的一个参数
import re
word="123_qwe_QQWE"
#********一下的为一行********
result=re.match(
"(?=.*[a-zA-Z])(?=.*[0-9])"
"(?=.*[_@\.!#%&])"
"[a-zA-Z_0-9@\.!@#%&]{6,20}$"
"",word).group()
#********以上的为一行********
print(result)
单行注释: #(注释代码)
多行注释: “”“(代码块)”“” 或 '''(代码块)'''
标识符:字母/下划线/数字组成,数字不能开头
注意:大小写区分
1.见名知意:
起一个有意义的名字,尽量做到一眼看上去就知道它的意思(提高代码可读性),例如:
姓名:name 学生:student 年龄:age
2.驼峰式命名:
2.1 小驼峰命名法则:第一个单词的首字母小写,从第二个单词开始及后面的单词的首字母大写,
例如:firstName getArticleList
2.2 大驼峰命名法则:每一个单词的首字母都要求大写:例如:
例如:GetArticleList
3.下划线连接法:
在程序中使用”_“连接单词:例如: my_name last_name
1.定义:
python一些具有特殊功能的标识符-----》关键字
关键字,是python中已经使用过的标识符,所以不允许开发者自定义和关键字名字相同的标识符
['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
print('hello world')
在python语言里 只要看见%操作符 它就是格式化输出;
常用格式化符号
格式符号 转换
%d 有符号的十进制整数
%s 通过字符串格式化
%c 字符
%u 无符号的十进制整数
%o 八进制整数
%x/X 十六进制整数
%e/E 索引符号
%f 浮点实数
#代码===========================
name = '张三'
age = 18
sex = '男'
address = '安徽安庆'
hobby = '敲代码'
print('张三')
print(name)
print('%s'%name)
print('%s%d%s%s%s'%(name,age,sex,address,hobby))
print('%s\n%d\n%s\n%s\n%s'%(name,age,sex,address,hobby),end='')
#结果===========================
张三
张三
张三
张三18男安徽安庆敲代码
张三
18
男
安徽安庆
敲代码
print(参数的类型:字符串/整形,end='')
end = '' 起到一个取消换行的作用 阻止print()自动换行
print()直接输出是一个空格 换行
\n 换行
使用函数input(),获取用户从键盘输入的数据
#输入 input()函数
height = input('请输入你的身高')
print(height)
"""
总结:
input函数()里面放的是提示信息 获取用户键盘返还的信息
input()返还的结果赋给一个变量
input()获取键盘返回的值都当做字符串进行处理
"""
#获取变量的数据类型 type()获取变量的数据类型 格式:type(变量名)
print(type(height))
注意:
在定义常量的时候一般将常量的名字全部大写(行业规则)
PI = 3.1415926
常量的特点:一旦定义,不能更改。
python没有任何机制保证常量不会被修改,没有提供定义常量的保留字。
总结:实际常量的值是可以修改的 后面学习将常量锁定 常量实质还是变量 。
* 局部变量
* 成员变量(全局变量)
#局部变量
def test1():
a = 10
b = 10
def test2():
a = 10
b = 20
# 以上函数中的变量----》局部变量
局部变量总结:
局部变量:
就是在函数内部定义的变量
不同的函数,可以定义相同名字的局部变量,各个变量之间不会发生干涉不会影响
局部变量的作用:为了临时保存数据需要在函数中定义变量来进行保存
#全局变量
定义:
如果一个变量,既能在一个函数中使用,
也能在另外一个函数中使用---》全局变量
"""
#定义一个全局变量
a = 100
def test3():
print(a)
def test4():
print(a)
test3()
test4()
"""
全局变量和局部变量名字相同的问题
"""
s = 100
def test5():
s = 200
print(s) #200
s = 300
print(s) #300
def test6():
print(s) #100
test5()
* global 关键字 修改全局变量
* 格式:global 需要修改变量名
# 没有加global修饰的全局变量
num = 11
def num01():
num = 12
return num
print(num01())
print(num)
print("*" * 30)
# 在外部加global修饰的全局变量
global num001
num001 = 110
def num011():
global num001
num001 = 100
return num001
print(num011())
print(num001)
print("*" * 30)
# 在函数内部加global修饰的全局变量
num002 = 110
def num012():
global num002
num002 = 100
return num002
print(num012())
print(num002)
print("*" * 30)
再来一个案例
print("*" * 30)
wendu = 0
def get_wendu():
# 想一下wendu=33不加注释的运行结果
# wendu = 33
global wendu
wendu = 34
def print_wendu():
print(wendu)
get_wendu()
print_wendu()
1.在函数外面定义的变量称为:全局变量
2.全局变量能够在所有的函数中被访问
3.如果在函数中修改全局变量,那么需要使用global关键字进行声明,否则出错
4.如果出现同名的现象,先到局部找---》全局-----》报错,这个被称为:就近原则
他们的本质的区别:
在于作用域
#案例:
def get_wendu():
wendu = 33
return wendu
def print_wendu(wendu):
print(wendu)
result = get_wendu()
print_wendu(result)
wendu = 0
def get_wendu1():
wendu = 34
# global wendu
wendu = 33
def print_wendu1():
print(wendu)
当不可变的数据类型作为全局变量: 需要用global声明,进行修改
当可变的数据类型作为全局变量: 不一定需要global声明
#案例:
test = []
def d():
test.append(2)
print(test)
d()
test1 = []
def e():
test1 = [1,2]
# global test1
test1 = [3,4]
# print(test1)
e()
print(test1)
test2 = [1,2]
def f(a):
a += a
print(a)
f(test2)
print(test2)
再来一个案例
# 没有加global修饰的全局变量--可变类型
list01 = [1, 2, 3, 4]
def list001():
list01.append(5)
return list01
print(list001())
print(list01)
print("*" * 30)
# 加global修饰的全局变量--可变类型
global list02
list02 = [6, 1, 2, 3, 4]
def list002():
global list02
list02.append(5)
return list02
print(list002())
print(list02)
#不可变
a = 1
def g():
a = 2
a += 1
print(a)
# global a
a = 4
g()
print(a)
Number(数字)
String(字符串)
List(列表)
Tuple(元组)
Set(集合)
Dictionary(字典)
Python3 的六个标准数据类型中:
不可变数据(3 个):Number(数字)、String(字符串)、Tuple(元组);
可变数据(3 个):List(列表)、Dictionary(字典)、Set(集合)。
python3包含int float bool complex(复数)
例如:14 + 5j
python2里面还有一个long长整形
python3只有一个int整形
type()函数可以获取变量的数据类型
a,b,c,d = 10,3.15,True,10 + 4j 交互赋值方式
#连续赋值
num = num2 = num3 = 10
#单独赋值
a = 10
b = 3.15
c = True
d = 10 + 4j
#isinstance(变量名称,预测的变量类型)获取变量的数据类型
s = 1234
print(isinstance(s,int))
"""
type()直接获取变量的数据类型 它不会认为子类和父类是相同的类型
isinstance() 预测一个是什么数据类型 它会认为子类和父类是相同数据类型
"""
#案例 整数/浮点/布尔/复数
#1.整数:我们可以定义任意数字整数 包含负整数 和数学里面写法一样
num1 = 10
num2 = 0 #0是特殊的整形
print(type(num1))
print(type(num2))
#2.浮点:带有小数点的数字
f = 3.15
f2 = 6.8
f3 = f + f2
print(type(f3))
#布尔类型 只有两个值 True和False
b = True
print(type(b))
#复数:由数字开头 后面包含字母
f = 10 + 4j
print(type(f))
print(f.real) #获取复数里面的实数
print(f.imag) #获取复数里面的虚数
#空值 在python里面使用None表示 None不能理解0
n = None
print(type(n))
函数 说明
int(x) 将x转换为一个整数
float(x) 将x转换为一个浮点数
complex(real,[,imag]) 创建一个复数
str(x) 将对象x转换为字符串
repr(x) 将对象x转换为表达式字符串 用的不多
tuple(x) 将序列转换为元祖
list(x) 将序列x转换为列表
chr(x) 将一个整数转换为一个字符
unichr(x) 将一个整数转换为unicode字符
ord(x) 将一个字符转换为整数
hex(x) 价格一个整数转换为一个十六进制的字符串
#定义一个字符串变量
str = '100'
print(type(str))
#将字符串转换为整形 int(变量名)
#str2 = int(str)
#print(type(str2))
#将字符串转换为浮点类型
#f = float(str)
#print(type(f))
#将字符串转换为列表
"""
list = list(str)
print(type(list))
print(list)
"""
#特殊的数字不能进行转换
"""
a = 'abc'
a = "12ddd"
b = int(a)
print(type(b))
"""
#必须是正整数或者负整数转换才有意义
print(int("+123"))
print(type(int("+123")))
print(int("-100"))
print(int("12 + 4")) #报错
print(int("20 - 5"))
int表示长整型,Python只有这一种整数类型,包含正整数和负整数
#
a = 123
b = -345
接下来的写法和上面的写法作用相同
a, b = 123, 345
print(a + b)
print(a - b)
print(a * b)
print(a / b)
*
输出结果
#
-222
468
-42435
-0.3565217391304348
float表示小数,只有这一种小数类型,包含正小数和负小数
#
i = 11.1
j = -22.2
print(i + j)
print(i - j)
print(i * j)
print(i / j)
输出结果
#
-11.1
33.3
-246.42
-0.5
Python3中表示真或假的类型
h = True
k = False
print(h + k)
print(h + 1)
print(h - k)
print(h * k)
print(h / k)# 报错
输出结果
1
2
1
0
Traceback (most recent call last):
File "Demos/Demo_Key.py", line 42, in
print(h / k)
ZeroDivisionError: division by zero
complex在Python中表示复数类型
这里的复数解释为常量和变量的组合
例如:k = 123+45j
123表示常量
45j表示变量
g = 123+45j
print(g)
print(g.real)
print(g.imag)
输出结果:
(123+45j)
123.0
45.0
作用:进行数值的运算
import math
#求绝对值
a = -5
print(math.fabs(a))
print(abs(-10))
#如果想查看某个函数 里面的参数 包括返回值 按住键盘上面ctrl键 再把鼠标移动到方法上面
#求浮点数的四舍五入的值 round(变量名,保留小数的位数)
print(round(3.5))
print(round(12.59,1))
但是到了python3.5的doc中,文档变成了"values are rounded to the closest multiple of 10 to the power minus ndigits; if two multiples are equally close, rounding is done toward the even choice." 如果距离两边一样远,会保留到偶数的一边。比如round(0.5)和round(-0.5)都会保留到0,而round(1.5)会保留到2。
#向上取整
print(math.ceil(3.1))
#向下取整
print(math.floor(3.9))
#取整数部分和小数部分mody()
print(math.modf(12.35))
#求平方根
x = 5
y = 2
print(math.pow(x,y))
随机数
1.直接查询API
2.直接调用dir
随机数使用的场景
数学 打游戏 安全领域
import random
#print(dir(random))
#返还一个随机的0-1之间的随机数
print(random.random())
#choice()返回随机的一个元素
print(random.choice('abcdefg'))
#randrange()随机返回一个元素 做微信随机抢红包
print(random.randrange(1,10,2))
"""
randrange(start,stop,step)
start起始值
stop结束值
step步长
"""
#shuffle()可以随机打乱列表里面的元素值
list = [3,1,6,20,4,True,'abc']
print(list)
random.shuffle(list)
print(list)
定义:
放在单引号 或者 双引号 里面的数字 字母 特殊字符 ----》字符串
格式:
name = '123'
name2 = "abc"
name3 = "@#"
注意:字符串里面的值不可改
#字符串的输出 print(变量名,end = '')函数 end取消换行
print('明天星期天')
str = '明天星期五'
print(str)
name = '张三' #声明了一个变量 变量的名称叫name 给它赋值张三
address = '上海'
print("我的姓名是:%s,我住在:%s"%(name,address))
input()函数可以获取键盘输入的信息,返还的结果当做字符串处理,需要报存到一个变量里面
#字符串的输入 input()函数
username = input('请输入你的用户名:')
password = input('请输入你的密码:')
if username == 'lishi' and password == '289001':
print('欢迎你%s回来'%username)
else:
print('用户名或者密码错误')
定义:
下标 ---- >编号
生活中的场景:
做火车--->找座位号
定义一个字符串变量
name = 'zhangsan'
格式: print(name[0])
#下标
names = 'wangwu'
"""
print(names[0])
print(names[1])
print(names[2])
print(names[3])
print(names[4])
print(names[5])
"""
#使用for循环获取
for temp in names:
print(temp)
定义:
截取变量里面的部分元素值---->切片
格式:[开始:结束:步长]
name = 'hello world'
print(name[0::]) #如果起始值是0 表示从头截取到尾部
print(name[3::]) #从起始值3开始 截取后面所有字符
print(name[:2:])
#从后往前截取 最后一个元素-1
print(name[::-2]) #如果步长负值 代表从后往前截取
print(name[:-1:])
#1.字符串相加
str = 'hello '
str2 = 'world'
str3 = str + str2 #字符串里面+是拼接
print(str3)
#2.输出5个world
print(str2 * 5)
#3.字符串里面替换 注意:String值不能修改
"""
name = 'abc'
name[0] = 'c'
print(name)
"""
name = 'hello world'
print(name[0::]) #如果起始值是0 表示从头截取到尾部
print(name[3::]) #从起始值3开始 截取后面所有字符
print(name[:2:])
#从后往前截取 最后一个元素-1
print(name[::-2]) #如果步长负值 代表从后往前截取
print(name[:-1:])
#1.换行 \n
print('hello \nworld')
#2.使用\\对\进行转义
print("hello\\world")
#3.\'
print("hello\'world")
#4.\"
print("hello\"world")
#5.\t 制表符
print('hello\tworld')
#6.如果转义的字符非常多 可以使用r
print(r"ddddd\tdddk\'kkkkkkk\kkkkk\"kkgdfdffdf")
print(name.replace("a", "w", 1))
print(name.capitalize())
print(name.title())
print(name.swapcase())
print(name.startswith("xiao"))
print(name.endswith("xiao"))
num = ord("a")
word = chr(num - 32)
print(word)
==width表示这个元素的总宽度,如果字符长度不够用空格补齐==
word = "abcdefg"
print(word.ljust(20))
print(word.ljust(20), "*")
==width表示这个元素的总宽度,如果字符长度不够用空格补齐==
print(word.rjust(20))
print(word.rjust(20), "*")
==width表示这个元素的总宽度,如果字符长度不够用空格补齐==
print(word.center(20))
print(word.center(20), "*")
print(word.zfill(20))
word = " word wordw "
print(word.strip())
print(word.strip().strip("w"))
aaa.aaa.aaa.txt
print(word.rfind("w"))
print(word.rfind("w", 14, 20))
print("hello01", end="\t")
print("hello02", end="\n")
print("hello03", end="\r")
print("hello04", end="\r\n")
print("hello05", end="\r")
print("hello06", end="\r")
输出结果:
#
hello01 hello02
hello04
hello06
列表介绍:
序列是Python中最基本的数据结构。
序列中的每个元素都分配一个数字 - 它的位置,或索引,第一个索引是0,第二个索引是1,依此类推。
列表是常用的Python数据类型,它可以作为一个方括号内的逗号分隔值出现。
列表可以进行的操作包括索引,切片,加,乘,检查成员。
此外,Python已经内置确定列表的长度以及确定最大和最小的元素的方法。
列表的数据项不需要具有相同的类型
列表格式:
列表名 = [列表选项1,列表选项2,…,列表选项n],
list1 = [1, 2, 3, 4, 5]
list2 = ["a", "b", "c", "d"]
list3 = [True, False]
list4 = ["a", 1, True, None]
list5 = []
代码:
print(list1)
print(list2)
print(list3)
print(list4)
print(list5)
print(type(list4))
print(type(list5))
运行输出结果:
#
[1, 2, 3, 4, 5]
['a', 'b', 'c', 'd']
[True, False]
['a', 1, True, None]
[]
#
想一想:list6 = [None],print(list6)在控制台运行输出的是什么结果
#
创建列表
list1 = [1, 2, 3, 4, 5]
list2 = ["a", "b", "c", "d"]
运行输出列表
print(list1)
print(list2)
运行输出结果
[1, 2, 3, 4, 5]
['a', 'b', 'c', 'd']
创建列表
list1 = ["a", "b", "c", "d"]
运行输出列表
print(list1[0])
print(list1[1])
print(list1[2])
print(list1[3])
运行输出结果:
#
a
b
c
d
使用for循环
namesList = ['xiaoWang', 'xiaoZhang', 'xiaoHua']
for name in namesList:
print(name)
运行输出结果:
xiaoWang
xiaoZhang
xiaoHua
#使用while循环
namesList = ['xiaoWang', 'xiaoZhang', 'xiaoHua']
length = len(namesList)
i = 0
while i < length:
print(namesList[i])
i += 1
运行输出结果:
xiaoWang
xiaoZhang
xiaoHua
namesList = ['xiaoWang', 'xiaoZhang', 'xiaoHua']
print(namesList * 2)
运行输出结果:
['xiaoWang', 'xiaoZhang', 'xiaoHua', 'xiaoWang', 'xiaoZhang', 'xiaoHua']
我们对数据常用的操作一般可以总结为:增、删、改、查,下面我们来学习关于列表的常用操作
namesList = ['xiaoWang', 'xiaoZhang', 'xiaoHua']
print(namesList[0])
print(namesList[1])
print(namesList[2])
运行输出结果:
xiaoHua
xiaoZhang
xiaoHua
想一想:print(namesList[3])在控制台运行输出的结果是什么
代码:
namesList = ['xiaoWang', 'xiaoZhang', 'xiaoHua']
print("更改前的nameList:%s" % namesList)
namesList[0] = "小王"
print("更改后的nameList:%s" % namesList)
运行输出结果:
更改前的nameList:['xiaoWang', 'xiaoZhang', 'xiaoHua']
更改后的nameList:['小王', 'xiaoZhang', 'xiaoHua']
通过append可以向列表中添加元素,添加的元素放在最后
namesList = ['xiaoWang', 'xiaoZhang', 'xiaoHua']
print("添加元素前的nameList:%s" % namesList)
namesList.append("xiaoMing")
print("添加元素后的nameList:%s" % namesList)
运行输出结果:
添加元素前的nameList:['xiaoWang', 'xiaoZhang', 'xiaoHua']
添加元素后的nameList:['xiaoWang', 'xiaoZhang', 'xiaoHua', '小明']
通过insert可以向列表指定位置添加元素
列表增加元素–insert(index, object)
namesList = ['xiaoWang', 'xiaoZhang', 'xiaoHua']
print("添加元素前的nameList:%s" % namesList)
namesList.insert(1, "小明")
print("添加元素后的nameList:%s" % namesList)
运行输出结果:
添加元素前的nameList:['xiaoWang', 'xiaoZhang', 'xiaoHua']
添加元素后的nameList:['xiaoWang', '小明', 'xiaoZhang', 'xiaoHua']
列表增加元素–extend(list)
namesList1 = ['xiaoWang', 'xiaoZhang', 'xiaoHua']
namesList2 = ['小王', '小张', '小华']
print("添加元素后的nameList:%s" % namesList1)
namesList1.extend(namesList2)
print("添加元素后的nameList:%s" % namesList1)
运行输出结果:
添加元素后的nameList:['xiaoWang', 'xiaoZhang', 'xiaoHua']
添加元素后的nameList:['xiaoWang', 'xiaoZhang', 'xiaoHua', '小王', '小张', '小华']
namesList1 = ['xiaoWang', 'xiaoZhang', 'xiaoHua']
namesList2 = ['小王', '小张', '小华']
namesList3 = namesList1 + namesList2
print(namesList3)
运行输出结果:
#
['xiaoWang', 'xiaoZhang', 'xiaoHua', '小王', '小张', '小华']
(in, not in, index, count)
in(存在):如果存在返回的结果为True,反之False
not in(不存在):如果不存在结果为True,反之False
index(str, start, end)查找元素第一次出现的下标
count(str)查找元素个数目
代码:
namesList1 = ['xiaoWang', 'xiaoZhang', 'xiaoHua']//获取用户要查找的名字
findName = input("请输入需要查找的名字:")//查找判断,是否存在
if findName in namesList1:
print("找到有这个人...")
elif findName not in namesList1:
print("查无此人....")
运行输出结果:
请输入需要查找的名字:aaa
查无此人....
请输入需要查找的名字:xiaoHua
找到有这个人...
index()案例:index /count
a = ["a", "b", "c", "b", "d", "a"]
print(a.index("b"))
print(a.index("b", 2, 5))
print(a.count("a"))
运行输出结果:
1
3
2
想一想:print(a.index("e"))和print(a.count("e"))运行输出什么结果
(del/pop/remove)
# 删除元素(del list[index])
word = ["a", "b", "c", "b", "d", "a"]
print("删除元素前的word:%s" % word)
del word[1]
print("删除元素后的word:%s" % word)
#运行输出结果:
删除元素前的word:['a', 'b', 'c', 'b', 'd', 'a']
删除元素后的word:['a', 'c', 'b', 'd', 'a']
# 删除元素(pop(index))
word = ["a", "b", "c", "b", "d", "e"]
print("删除指定位置元素", word.pop(1))
print("删除默认位置元素", word.pop())
#运行输出结果:
删除指定位置元素 b
删除默认位置元素 e
# 删除元素(remove(object))
word = ["a", "b", "c", "b", "d", "e"]
print("删除元素前的word:%s" % word)
word.remove("a")
print("删除元素后的word:%s" % word)
word.remove("a")
列表排序sort(reverse=False):
word = ["a", "b", "c", "b", "d", "e"]
print("排序前的word:%s" % word)
word.sort(reverse=False)
print("顺序排序后的word:%s" % word)
word.sort(reverse=True)
print("逆序排序后的word:%s" % word)
运行输出结果:
排序前的word:['a', 'b', 'c', 'b', 'd', 'e']
顺序排序后的word:['a', 'b', 'b', 'c', 'd', 'e']
逆序排序后的word:['e', 'd', 'c', 'b', 'b', 'a']
类似while、for循环的嵌套,列表也支持嵌套
一个列表中的列表作为一个元素
格式:列表名 = [ [ ], [ ], [ ] ]
例如:schoolNames = [["清华大学","北京大学"],["哈尔滨佛学院"],[]]
namesList = [["赵毅", "钱尔", "孙三"], ["里斯", "周武"], ["吴柳", "郑琦"]]
for cls in namesList:
print(cls, end=",")
print()
运行输出结果:
赵毅,钱尔,孙三,
里斯,周武,
吴柳,郑琦,
word = ["a", "b", "c", "b", "d", "e"]
print(max(word))
print(min(word))
运行输出结果:
a
e
- 元组概述
- python的元组和列表类似,不同之处在于元组的元素不能修改,
- 元组格式:
- 元组名 = (元组元素1,元组元素2.....元组元素n)
代码:
tuple1 = ()
tuple2 = (1, 2, 3)
tuple3 = (1, 2, 3, "hello", True)
print(tuple1)
print(tuple2)
print(tuple3)
print(type(tuple1))
print(type(tuple2))
print(type(tuple3))
运行输出结果:
(1, 2, 3)
(1, 2, 3, 'hello', True)
做一做:tuple0 = (1),print(type(tuple0))运行输出结果是什么
tuple4 = (1, 2, 3, "hello", True)
print(tuple4[2])
print(tuple4[3])
运行输出结果:
#
3
hello
tuple5 = (1, 2, 3, "hello", True)
for t in tuple5:
print(t)
运行输出结果:
#
1
2
3
hello
True
#
tuple1 = (1,2,3)
print(tuple1 * 3)
运行输出结果:
#
(1, 2, 3, 1, 2, 3, 1, 2, 3)
==元组内一旦创建,不可更改,==可修改的是元组内的可变类型例如:数组
tuple5 = (1, 2, 3, 4, True, [5, 6, 7])
# tuple5[0] = 100 #报错,元组不能修改
# tuple5[-1] = [7,8,9] #报错,
tuple5[5][0] = 500
print(tuple5)
运行输出结果
(1, 2, 3, 4, True, [500, 6, 7])
del可以删除元组,但是后果很严重。。。
#
tuple6 = (1, 2, 3)
del tuple6
print(tuple6)
运行输出结果:
Traceback (most recent call last):
File "/Day06/Tuple_Demo01.py", line 61, in
print(tuple6)
NameError: name 'tuple6' is not defined
* 试一试:del tuple6[1]运行输出什么结果
tuple1 = (1, 2, 3)
tuple2 = (4, 5, 6)
tuple3 = tuple1 + tuple2
print(tuple3)
print(type(tuple3))
print(tuple1)
print(tuple2)
运行输出结果:
#
(1, 2, 3, 4, 5, 6)
(1, 2, 3)
(4, 5, 6)
使用in,not in可以判断某个元素是否在目标元组
tuple4 = (1, 2, 3)
print(3 in tuple4)
print(3 not in tuple4)
运行输出结果:
True
False
格式: 元组名[开始 : 结束 :步长](含头不含尾)
案例:
tuple6 = (1, 2, 3, 4, 5, 6, 7, 8)
print(tuple6[:])
print(tuple6[3:7])
print(tuple6[3:])
print(tuple6[:7])
print(tuple6[:-1])
print(tuple6[-1::-1])
运行输出结果:
#
(1, 2, 3, 4, 5, 6, 7, 8)
(4, 5, 6, 7)
(4, 5, 6, 7, 8)
(1, 2, 3, 4, 5, 6, 7)
(1, 2, 3, 4, 5, 6, 7)
(8, 7, 6, 5, 4, 3, 2, 1)
元组的嵌套(二维元组),元素是一维元组
格式:元组名 = ((),(),()…)
案例:
tuple7 = ((1, 2, 3), (4, 5, 6), (True, False))
print(tuple71)
for tuple0 in tuple7:
for num in tuple0:
print(num, end=",")
print()
运行输出结果:
#
5
1,2,3,
4,5,6,
True,False,
字典格式
格式:{key1 : value1, key2 : value2, key3 : value3, ....}
创建字典
定义一个变量info为字典类型
info = {"name" : "zhangsan", "id" : 1234, "address" : "北京"}
变量名["键"] = 数据时,如果该键在字典中不存在,会自动创建
info = {"id": 100, "address": "北京", "name": "zhangsan"}
print("添加元素前的字典info:", info)
info["phoneNum"] = 10086
print("添加元素后的字典info:", info)
运行输出结果:
#
添加元素前的字典info: {'id': 100, 'address': '北京', 'name': 'zhangsan'}
添加元素后的字典info: {'id': 100, 'address': '北京', 'name': 'zhangsan', 'phoneNum': 10086}
==变量名["键"] = 数据时,如果该键在字典中存在,会改变原值==
==变量名["键"] = 数据时,如果该键在字典中不存在,会自动创建==
info = {"id": 100, "address": "北京", "name": "zhangsan"}
print("修改前的字典info:", info)
newAddr = input("请输入您所在的城市:")
info["address"] = newAddr
newAge = int(input("请输入您的年龄:"))
info["age"] = newAge
print("修改后的字典info:", info)
运行输出结果:
#
修改前的字典info: {'id': 100, 'address': '北京', 'name': 'zhangsan'}
请输入您所在的城市:上海
请输入您的年龄:18
修改后的字典info: {'id': 100, 'address': '上海', 'name': 'zhangsan', 'age': 18}
del :删除指定的元素
clear():清空字典
案例:
del案例:
info = {"id": 100, "address": "北京", "name": "zhangsan"}
print("删除元素前的字典info:", info)
del info["address"]
print("删除元素后的字典info:", info)
运行输出结果:
#
删除元素前的字典info: {'id': 100, 'address': '北京', 'name': 'zhangsan'}
删除元素后的字典info: {'id': 100, 'name': 'zhangsan'}
clear()案例:
# clear()
print("clear()前的字典info:", info)
info.clear()
print("clear()后的字典info:", info)
运行输出结果:
#
clear()前的字典info: {'id': 100, 'name': 'zhangsan'}
clear()后的字典info: {}
get()函数:在我们不确定字典中是否存在某一个键而又想获取它的值,可以使用get(),可以设置默认值
案例:
info = {"id": 100, "address": "北京", "name": "zhangsan"}
age = info.get("age") # age键不存在,所以age的值为None
print(age)
age = info.get("age", 18)
print(age)
运行输出结果:
#
None
18
info = {"id": 100, "address": "北京", "name": "zhangsan"}
- 字典长度- len(dict)
len0 = len(info)
print("字典info的长度是:", len0)
字典info的长度是: 3
- 获取所有的键key--dict.keys()
keys = info.keys()
print("字典info的键集合是:", keys)
字典info的键集合是: dict_keys(['id', 'address', 'name'])
- 获取所有的值value- dict.values()
values = info.values()
print("字典info的值集合是:", values)
字典info的值集合是: dict_values([100, '北京', 'zhangsan'])
- 获取所有的键值对- dict.items()
items = info.items()
print("字典info的键值对集合是:", items)
字典info的键值对集合是: dict_items([('id', 100), ('address', '北京'), ('name', 'zhangsan')])
4、遍历字典 - 使用for循环可以搞定
# 字典的遍历
# 遍历字典中的key
info = {"id": "100", "address": "北京", "name": "zhangsan"}
print("--------遍历字典中的key--------")
b = info.keys()
print(type(b))
for key in b:
print(key, end=",")
print("\n--------遍历字典中的value--------")
# 遍历字典获取字典中所有的值
c = info.values()
for value in c:
print(value, end=",")
print("\n--------遍历字典中的键值对--------")
# 获取键值对
itmes = info.items()
for itme in itmes:
print(itme)
print("\n--------遍历字典中的键值对改良版--------")
# 改进
for key, value in itmes:
print("key = %s,value = %s" % (key, value))
运行输出结果:
--------字典的遍历--------
--------遍历字典中的key--------
id,address,name,
--------遍历字典中的value--------
100,北京,zhangsan,
--------遍历字典中的键值对--------
('id', '100')
('address', '北京')
('name', 'zhangsan')
key = id,value = 100
key = address,value = 北京
key = name,value = zhangsan
案例:
chars = ['a', 'b', 'c', 'd']
i = 0
for chr in chars:
print("%d %s"%(i, chr))
i += 1
运行输出结果:
0 a
1 b
2 c
3 d
第二种方式:使用enumerate()解决
print("第二种方式:")
for i, c in enumerate(chars):
print(i, c)
运行输出结果:
0 a
1 b
2 c
3 d
集合与之前的列表和元组类似,可以存储多个类型数据,这些数据不能重复
创建集合案例:
set01 = set([1, 6, 9, 3, 6])
set02 = set({"id": "100", "address": "北京", "name": "zhangsan"})
set03 = {} # 创建的不是集合,是字典
set04 = set("abcde")
print(set01)
print(set02)
print(set03)
print(set04)
print(type(set03))
print(type(set04))
运行输出结果:
#
{1, 3, 6, 9}
{'name', 'id', 'address'}
{}
{'e', 'a', 'c', 'd', 'b'}
集合添加数据案例:
# 集合添加元素
print("---------add---------")
# 添加add
s1 = set([1, 2, 3, 4, 5])
s1.add(6)
print(s1)
s1.add(3) # 添加重复的元素,没有效果
print(s1)
运行输出结果:
#
---------add---------
{1, 2, 3, 4, 5, 6}
{1, 2, 3, 4, 5, 6}
读一下代码,说出运行结果:
s1.add([7, 8, 9]) # set的元素不能是列表,列表是可变的
print(s1)
s1.add({1: "haha"}) # set的元素不能是字典,字典也是可变的
print(s1)
s1.add(7, 8, 9) # set的元素不能连续添加
print(s1)
s1.add((7, 8, 9)) # set的元素可以是字典,字典也是不可变的
print(s1)
update()案例:
# 插入(更新)update()
# 可以插入list/tuple/String打碎插入(无序,去重)
print("----------Update()----------")
s2 = set([1, 2, 3])
s2.update([4, 5, 6])
print(s2)
s2.update((9, 10))
print(s2)
s2.update("haha")
print(s2)
s2.update("哈哈")
print(s2)
运行输出结果:
#
----------Update()----------
{1, 2, 3, 4, 5, 6}
{1, 2, 3, 4, 5, 6, 9, 10}
{'h', 1, 2, 3, 4, 5, 6, 9, 10, 'a'}
{'h', 1, 2, 3, 4, 5, 6, 9, 10, '哈', 'a'}
删除集合元素使用remove(object)
删除元素案例:
# 删除集合元素
print("------remove------")
# 删除remove()
s3 = set([1, 2, 3, 4, 5])
s3.remove(4) # 删除是具体的元素
print(s3)
s3.remove(9) # 这个元素是不存在的
print(s3)
运行输出结果:
------remove------
{1, 2, 3, 4, 5}
{1, 2, 3, 5---}
删除不存在元素:
# 删除集合元素
print("------remove------")
# 删除remove()
s3 = set([1, 2, 3, 4, 5])
s3.remove(9) # 这个元素是不存在的
print(s3)
运行输出结果:
Traceback (most recent call last):
File "/Day06/Set_Demo01.py", line 58, in
s3.remove(9) # 这个元素是不存在的
KeyError: 9
遍历集合案例:
# 遍历集合
print("---------for循环遍历集合——----")
s4 = set([1, 2, 3, 4, 5])
for i in s4:
print(i, end=",")
print("-------带索引的遍历方式-------")
s5 = set("床前明月光")
for index, i in enumerate(s5):
print(index, i)
运行输出结果:
#
1,2,3,4,5,
-------带索引的遍历方式-------
0 前
1 床
2 月
3 光
4 明
交集和并集案例:
print("--------交集-------")
# 交集,使用运算符 "&"
s5 = set([1, 2, 3])
s6 = set([4, 5, 6, 2, 3])
# 交集 &
s7 = s5 & s6
print(s7)
print("--------并集-------")
# 并集,使用运算符 "|"
s8 = s5 | s6
print(s8)
print(type(s8))
运行输出结果:
#
--------交集-------
{2, 3}
--------并集-------
{1, 2, 3, 4, 5, 6}
下面的例子以a = 10 b = 20 为例进行计算
运算符 描述 实例
+ 加 两个对象相加 a + b 输出的结果 30
- 减 两个对象进行相减 a - b 输出的结果 -10
* 乘 两个对象进行相乘 a * b 输出的结果 200
/ 除 两个对象进行相除 b / a 输出的结果 2
// 取整 返回商的整数部分 9//2 输出的结果 4 9.0//2.0 输出的结果 4.0
% 取余 返回除法的余数 b % a 输出的结果 0
** 幂 返回x的y次幂 a ** b 10的20次方 输出的结果
运算符 描述 实例
= 赋值运算符 把=号右边的结果赋值给左边的变量 num = 1+2*3
赋值运算符的基本格式:
变量 = 表达式
功能:
计算了等号右侧的表达式的值,赋值给等号左边的变量,赋值结束后的变量
a = 3 c = 10
+= 加法赋值运算 c += a ===> c = c + a
-= 减法赋值运算 c -= a ===> c = c - a
*= 乘法赋值运算 c*= a ===> c = c * a
/= 除法赋值运算 c /= a ===> c = c / a
%= 取余法赋值运算 c %= a ===> c = c % a
**= 幂法赋值运算 c **= a ===> c = c ** a
//= 取整法赋值运算 c //= a ===> c = c // a
比较运算符
运算符 描述 示例
== 检查两个操作数是否相等,如果是条件为真(True),反之为否(False) 注意:不仅比较大小,还比较类型
例:print(10 == '10') False
!= 检查两个操作数是否相等,如果是值不相等(True),反之False
例:print(10 != '10') True
> 检查左操作数的值是否大于右操作数的值,如果是返回True,反之False
< 检查左操作数的值是否小于于右操作数的值,如果是返回True,反之False
>= 检查左操作数的值是否大于等于右操作数的值,如果是返回True,反之False
<= 查左操作数的值是否小于等于右操作数的值,如果是返回True,反之False
逻辑运算符
运算符 逻辑表达式 描述 示例
and x and y 布尔“与” 如果x为false,x and y 返回false,否则返回y的计算值
or x or y 布尔“或” 如果x为True 返回True 反之返回y的计算值
not not x 布尔“非” 如果x为True 返回的False,如果False返回的True
#代码=======================
# 逻辑运算符
a = True
b = 10
print(a and b)
print(a or b)
print(not a)
a = False
b = 10
print(a and b)
print(a or b)
print(not a)
#结果=======================
10
True
False
False
10
True
概述:
按照位运算符把数字转换为二进制来计算
python中的位运算法则有哪些?
运算符 描述 示例
& 按位与运算符:参与运算的两个值,如果两个相应位都是1,则该位的结果为1,否则为0
| 按位或运算符:只要对应的两个二进制位有一个为1,结果就为1,反之为0
^ 按位异或运算符:当两个二进制位不相同时,结果为1,反之为0
~ 按位取反运算符:对数据的每一个二进制位进行取反,即把1变为0,0变为1 ~x类似-x-1 10 -11
<< 左移运算符:运算数的每一个二进制位全部向左移若干位,由<<右边的数字指定了移动的位数,高位丢弃,低位补0
>> 右移运算符:把>>左边的运算数的各个二进制位全部右移若干位,由>>右边数字控制移动的位数
当满足某个条件的时候 我们要做的事情
生活中的场景
做地铁/火车 需要先安检 如果有票就能进站 或者不允许进站
开发中的场景
用户登陆注册 判断登陆时候填写信息是否和注册提交给后台的保持一致
例子:判断重要的日期 五一劳动节,情人节,发工资
思考:单分支条件语句,如果条件为真执行要做的事情 条件为假不会有任何输出,我如果想条件为假的结果
作用:if语句用来进行判断:
if 要判断的条件:
条件成立,要做的事
if的基本格式
if 条件:
要做的事情
if...else
格式:
if 条件:
满足条件,做事情1
满足条件,做事情2
满足条件,做事情3
....
else:
不满足条件,做事情1
不满足条件,做事情2
不满足条件,做事情3
练习:
要求,从键盘获取自己的年龄,判断是否大于等于18,如果条件成立“XXXX”
age = int(input('请输入你的年龄'))
if age >= 18: #执行条件为真的结果
print('成年了')
else: #执行条件为假的结果
print('未成年')
#案例,进火车站检票 如果有票可以进站 或者不允许进站
ticket = 0 #1表示有票 0表示无票
if ticket == 1:
print('有车票可以进站')
else: #执行条件为假的结果
print('没有车票,请先购票')
练习:
要求:从键盘输入刀子的长度,如果刀子长度没有超过10cm,允许上火车,反之不允许
knife1 = input('请输入刀子的长度:')
knife = int(knife1) #int()函数把input()函数返还的字符串先转换成数字类型
if knife <= 10: #满足进站的条件 执行条件为真的结果
print('可以进站')
else: #执行条件为假的结果
print('不允许进站')
拓展
#if比较运算符
age = 17
if age >= 18:
print('可以进网吧了')
else:
print('未成年人不准进网吧')
#if逻辑运算符 or
my = input('你去吗?')
mywife = input('你去吗?')
if my == '去' or mywife == '去':
print('去买菜')
else:
print('下馆子')
#if逻辑运算符 and
my = input('你去吗?')
mywife = input('你去吗?')
if my == '去' and mywife == '去':
print('可以领证了')
else:
print('再等等,过段时间再去')
#案例:if逻辑运算符not
age = 16
if not(age >= 18):
print('成年了')
else:
print('未成年')
#案例3:if逻辑运算符 ---白富美
color = input('你白吗?')
money = float(input('你富吗?'))
beautful = input('你美吗')
#带有小数点的浮点型 属于数字类型
if color == '白' and money >= 10000000 and beautful == '美':
print('白富美')
else:
print('--------')
1.if单分支条件语句 当条件为真执行要做的事情 条件为假不会有任何输出 如果我想输出条件为假的结果
2.if else 多分支条件语句 当条件为真执行要做的事情 条件为假执行else后面的语句 如果我们有多个条件都为真 只要满足就可以做对应的事情
格式:
elif 的使用格式:
if 条件1:
事情1
elif 条件2:
事情2
elif 条件3:
事情3
else: #执行条件为假的结果
要做的事情
说明:
当条件1满足时,执行事情1,然后整个if语句结束
当条件1不满足,那么需要判断条件2,如果条件2满足,执行事情2,然后整个if语句结束
当条件1和2都不满足,如果条件3满足,执行事情3,然后整个if语句结束
案例:
#if...elif案例
#根据考试的成绩,判断学生的等级
#案例:通过键盘录入的方式获取学生的成绩(Number类型中的int)
score = 59
if score == 60:
print('D')
elif score > 60 and score <= 75:
print('C')
elif score > 75 and score < 90:
print('B')
elif score >= 90:
print('A')
else: #以上条件都不满足 执行else条件为假的结果
print('你要补考')
注意:
elif必须和if一起使用,否则出错
练习:
根据用户的输入,判断是星期几,用户输入的数值范围为1~7(正整数)
条件语句里面再嵌套条件语句
if 条件1:
满足条件1,做事情1
满足条件1,做事情2
满足条件1,做事情3
.....(省略)
if 条件2:
满足条件2,做事情1
满足条件2,做事情2
满足条件2,做事情3
说明:外层的if判断,if...else
内层 if...else
# if语句嵌套
#案例,火车安检,先验票,再检查有没有携带违禁品 如果刀子长度没有超过10cm,允许上火车
nicket = 1 #1有票 0无票
knife = 12 #单位cm
#1.先检查用户是否有票
if nicket == 1:
print('通过安检,可以进站')
if knife <= 10:
print('可以上车了')
else:
print('携带违禁物品,先抓起来暴打一顿,再送公安局')
else:
print('请先买票再进站')
石头 剪刀 布
要求:
电脑随机生成一个0~2之间的正整数0,1,2,剪刀(0),石头(1),布(2),要求用户通过键盘录入的方式输入0~2之间的正整数,产生结果:
# 石头剪刀布游戏===========================================
# import random
# listuser = ['剪刀','石头','布']
# jiqiuser = random.choice(listuser)
# User=input('输入的石头、剪刀或者布')
# print(jiqiuser)
# if (User=='石头' and jiqiuser=='剪刀') or (User=='剪刀' and jiqiuser=='布') or (User=='布' and jiqiuser=='石头'):
# print('你赢了')
# elif User==jiqiuser:
# print('平手')
# else:print("你输了")
#===========================================
生活中的场景
电风扇 跑道
软件开发场景
总结: 在程序开发过程中 如果相同的代码执行多次 我们就可以使用循环,循环不是必须的
提高代码的重复使用率,一般应用在开发中
格式
while(循环的条件): 如果循环条件满足
做事情1,
做事情2,
做事情3
案例:循环输出1-5的数字
案例1:
计算1~100之间的累计和(包含1和100)
案例2:
计算1~100之间偶数的累计和(包含1和100)
思考:while循环当条件为真执行对应结果 为假就不会执行 如果想输出条件为假的结果 while else 类似
if else语句
格式:
while 判断表达式:
语句1
else:
语句2
逻辑:
在条件语句(判断表达式)为false,执行else中的语句2
案例:循环输出数字1-3
while循环,while里面嵌套一个while
格式:
while 条件1:
条件1满足,做事情1
条件1满足,做事情2
条件1满足,做事情3
.....
while 条件2:
条件2满足,做事情1
条件2满足,做事情2
条件2满足,做事情3
案例1.打印一个矩形
******
******
******
******
代码:
# 打印一个矩形===========================================
i = 1
while ( i <= 4):
j = 1
while(j <= 6):
print("*",end='')
j +=1
else:
print()
i +=1
# 非嵌套=====================================
i = 1
while ( i <= 24):
print("*",end="")
if i%6==0:
print()
i +=1
# ==========================================
案例2:
打印杨辉三角
*
* *
* * *
* * * *
* * * * *
代码:
# 杨辉三角===================================
i = 1
while (i <= 5):
j=1
while (j <= i):
print("* ",end='')
j+=1
print()
i+=1
# ==========================================
案例3:
打印九九乘法表
代码:
i = 1
while(i <= 9):
j = 1
while (j <= i):
print("%d*%d=%d "%(i,j,i*j),end='')
j+=1
i+=1
print()
和while一样 也能够进行数据的循环
循环序列的项目 String
格式:
for 临时变量 in 字符串或者列表
执行循环对应的结果
else:
执行不满足循环条件的结果
#案例:循环一个字符串里面每一个字符
#案例:循环一个空字符串
#循环输出1-10的结果
拓展:
enumerate()枚举函数 可以同时获取下标和元素值
语法格式:
for 临时变量1 in 字符串或者列表:
for 临时变量2 in 字符串或者列表:
执行的代码
#输出5*5的矩形
#打印九九乘法表
1.cpu满负荷工作 损坏计算机硬件
2.内存溢出
语法格式:
while True:
执行的代码
需要有一个结束的条件
#总结:终止程序的执行 后面代码不会继续执行
#总结:跳出当前循环 后面的会继续循环执行
1.break,continue一般使用在循环语句里面 在if条件语句使用
数据的存储
数据存储到计算机
运行速度快 存储海量数据 读取运算方便
数据存储到计算机什么地方?
存储到内存里面去了
数据是如何存储到内存里面
计算机很大一部分功能存储数据 存储器存储 类似内存条
内存?
抽象的概念
一个状态 1开启 0关闭
一个房间假设装8个开关 控制灯的打开或者关闭
一个房间我们称它为一个字节 每一个开关称为位
1字节= 8位
房间有个编号18 相当于是门牌号
计算机以二进制方式保存我们的数据到内存里面
0 1
内存存储数据的单位
1bit
8bit = 1字节
1024字节 = 1k
1024k = 1M
1024M = 1G
1024G = 1T
1024T = 1P
进制:进位的计数
生活中最常见的进制----》十进制1,2,3,4,5,6,7......
常见的进制分为:
二进制
八进制
十进制
十六进制
二进制:
任何数据在计算机中都是以二进制的形式存在,二进制早期由电信开关演变而来
特点:
由0,1组成,0b开头,逢二进一
例如:
0 + 0 = 0
0 + 1 = 1
1 + 1 = 10
11 + 1 = 100
八进制:
有数字0~7组成,逢八进一 ,以0o开头0,1,2,3,4,5,6,7 逢八进一
例如:
1 + 7 = 10
1 + 3 = 4
特定:
0~9数字组成,逢十进一,整数的默认是十进制
1 + 9 = 10
10 + 3 = 13
特点:
十六进制的范围0~9 A~F 0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f
逢16进1,以0x开头
1 + f = 10
1.十进制转换为二进制
做除法,余数逆序
10(10)---->1010(2)
10/2 5 0
5/2 2 1
2/2 1 0
1/2 0 1
2.十进制转八进制
10(10)----->12(8)
10/8 1 2
1/8 0 1
3.十进制转换为十六进制
直接除以16,余数在10~15之间用a~f表示
10(10)----》a
11(10)-----b
4.二进制转10进制
当前的数字,乘以2的位数的次方,最后相加
10进制转换2进制 1010
0*2^0 + 1*2^1 + 0*2^2 + 1*2^3 = 10
5.八进制转二进制
一转三位,八进制中的1位相当于二进制中的三位,转换的时候按照十进制进行转换
例如:65---->110101
6/2 3 0
3/2 1 1
1/2 0 1
5/2 2 1
2/2 1 0
1/2 0 1
6.二进制转换为八进制
三位转1位,从低位取,高位不够补0
110101(2)----》 65(8)
7.十六进制----》二进制
一位转4位
十六进制的一位相当于二进制的4位,转换时按照十进制进行转换
a4(16)----->1010 0100(2)
a ---> 1010
4 -----> 0100
8.二进制转为十六进制
四转1 从低位取,高位不够补0
补充:
十进制转换为八进制或则十六进制
(可以先将10----》2---》8/16)
0000 1010
1 1 1 1 1 1 1 1
128 64 32 16 8 4 2 1
可以使用python中函数实现
下面的符号对应进制数
b : 二进制
d : 十进制
o : 八进制
x : 十六进制
十进制转换二进制 ----》 bin(10)
十进制转换为八进制 ---》 oct(10)
十进制转换为十六进制 ----》 hex(10)
二进制转换为十进制 ----- eval("0b1010")
八进制转换为十进制 ----- int(参数1,参数2):参数1:需要转换的数,参数2,进制的类型
print(int('0o12',8))
十六进制转十进制 ---- int(参数1,参数2):参数1:需要转换的数,参数2,进制的类型
#将10进制15转换2进制
print(bin(15))
#将10进制15转换8进制
print(oct(15))
#将10进制15转换为十六进制
print(hex(15))
#二进制转换为十进制
print(eval('0b1010'))
#八进制转换为十进制
print(int('0o12',8))
#十六进制转十进制
print(int('0xa',16))
概述:
数据存储:计算机的存储数据,先开辟一个内存空间,在存储数据,计算机中开辟内存的最小单位是字节,二进制表示数据的存储 0和1 用高位标识符符号表示数值符号(+/-),1表示负数 0:正数
原码/反码/补码是数值运算的基础,在计算机中,数值运算是基于二进制数,底层是二进制运算,使用高位标识符 1表示负数 0:正数
基础定义:
原码:
就是二进制定点表示法,即最高为为符号位,0:正数,1:负数,其余的位数表示数值的大小
通过一个字节
10 0000 1010
-10 1000 1010
反码:(负数的反码除符号位以外,按位取反)
正数的反码和原码相同,负数的反码是对其原码逐位取反(1变0,0变1),但是符号位不变
+10 反码 0000 1010
-10 反码 1111 0101
补码:(负数的补码是按位取反,末尾加一)
正数的补码和原码一样,负数的补码是在其反码的末尾加1
+10 补码 0000 1010
-10 补码 1111 0110
注意:
计算机中都是以补码的形式存在
问题:
在计算机中,为什么不用原码和反码而用补码?
因为原码和反码不准确,而使用补码才准确
二进制转为十进制
1.使用原码计算
10-10
+10 0000 1010
-10 1000 1010
-----------------------------------
1001 0100 4+16 =-20
2.使用反码计算
10-10
+10 0000 1010
-10 1111 0101
--------------------------------
1111 1111 10000000 ===》 -0
3.使用补码计算
10-10
+10 0000 1010
-10 1111 0110
---------------------------
0000 0000 0
练习:
分别计算以下补码表示的十进制数是多少?
二进制
1.0b0000 1111 ------> 15
2. 0b1111 1111 -----》(将补码转换反码)0b1111 1110 __---->(反码再转原码)0b1000 0001 -1
3.0b1000 0001 ---->0b1000 0000 -----> 0b1111 1111 -127
4.~6取反(1变0,0变1)
6 ----》 二进制 ---》 0000 0110
取反
~6 1111 1001 补码(计算在存储数据时按补码进行存储)
1111 1001 补码
1111 1000 反码
1000 0111 原码
---------
Python的生成器是一个返回可以迭代对象的函数。
先看案例:
#创建一个列表,元素为0--20以内的偶数
list01 = [2, 4, 6, 8, 10, 12, 14, 16, 18]
list02 = [x * 2 for x in range(1, 10)]
Generator01 = (x * 2 for x in range(1, 10))
print(list01)
print(list02)
print(Generator01)
for i in Generator01:
print(i, end=",")
运行输出结果:
#
[2, 4, 6, 8, 10, 12, 14, 16, 18]
[2, 4, 6, 8, 10, 12, 14, 16, 18]
at 0x0000014043D37200>
2,4,6,8,10,12,14,16,18,
创建生成器的方式有多种,只要把一个列表生成式的[]改成()
创建list和Generator区别在于外层[],(),list表示一个列表,Generator表示生成器
遍历生成器内容:
# next
# 定义一个生成器
Generator = (x * 2 for x in range(5))
temp = next(Generator)
print(temp)
temp = next(Generator)
print(temp)
temp = next(Generator)
print(temp)
temp = next(Generator)
print(temp)
temp = next(Generator)
print(temp)
temp = next(Generator)# 注意:如果一直写next()函数,当超出了元素的个数范围的时候会直接报错
print(temp)
运行输出结果:
#
0
2
4
6
8
Traceback (most recent call last):
File "/Day06/Generator_Demo01.py", line 24, in
temp = next(Generator)
StopIteration
# 循环遍历
Generator = (x*2 for x in range(5))
for temp in Generator:
print(temp)
运行输出结果:
#
0
2
4
6
8
生成器保存的是一个算法,每次调用next()函数,就能计算出生成器下一个元素的值,直到最后一个元素,
如果超出了元素的最大长度范围,报错,
通过for循环来迭代他,并且不用关心超出界限的问题
格式: def 函数名():
方法体语句
练习:菲波拉锲数列
- 1 1 2 3 5 8 13 除第一个和第二个外,任意的数都是由前两个数相加得到
a = 0
b = 0
c = 1
while a < 5:
temp = c
c = b + c
b = temp
a += 1
print(b)
def fib1():
a = 0
b = 0
c = 1
while a < 5:
temp = c
c = b + c
b = temp
a += 1
print(b)
fib1()
def fib2():
a = 0
b,c = 0,1
while a < 5:
print(c)
b,c = c , b+ c
# b = c
# c = b + c
a += 1
fib2()
print("-----fib3()---------")
def fib3():
a = 0
b , c = 0 ,1
while a < 5:
# print(c)
yield c
b , c = c, b + c
a += 1
f = fib3()#生成器
print(f)
print(next(f))
print(next(f))
print(next(f))
print(next(f))
print(next(f))
运行输出结果:
#
-----fib3()---------
1
1
2
3
5
yield是一个类似return的关键字,迭代一次遇到yield的时候返回(右侧,后面的值)
总结:
下一次迭代时,从上一次迭代遇到yield后面的代码(下一行)开始执行
yield返回一个值,并且记住返回值的位置,
下次迭代的时候就从这个记录的位置开始
输出时注意调用next()的次数,超出内容会报错
迭代:
访问集合元素的一种方式
迭代器:
可以被next()函数调用并且不断的返回下一个值的对象(迭代器 Iterator)
迭代对象:
是一个可以记住遍历位置的对象
迭代器对象从集合的第一个元素开始访问,直到所有的元素访问完毕为止
迭代器的特点:
只能往前,不会后退
直接可用for循环遍历的数据类型有哪些?
这些可以直接作用与for循环的对象的统称----》可迭代对象(Iterable)
怎么判断是否可以迭代?
from collections import Iterable
a = isinstance([],Iterable)
b = isinstance((),Iterable)
c = isinstance({},Iterable)
d = isinstance("aaaa",Iterable)
e = isinstance(1000,Iterable)#false
f = isinstance((x for x in range(5)),Iterable)
print(a)
print(b)
print(c)
print(d)
print(e)
print(f)
运行输出结果:
#
True
True
True
True
False
True
迭代器:
可以被next()函数调用并且不断的返回下一个值的对象(迭代器 Iterator)
判断一个元素是不是迭代器:isinstance(ocject, Iterator)
print("--------Iterator---------")
from collections import Iterator
a = isinstance([], Iterator)
b = isinstance((), Iterator)
c = isinstance({}, Iterator)
d = isinstance("aaaa", Iterator)
e = isinstance(1000, Iterator)
f = isinstance((x for x in range(5)), Iterator)
print(a)
print(b)
print(c)
print(d)
print(e)
print(f)
运行输出结果:
--------Iterator---------
False
False
False
False
False
True
Python中 list、truple、str、dict这些都可以被迭代,但他们并不是迭代器。为什么?
因为和迭代器相比有一个很大的不同,list、truple、map、dict这些数据的大小是确定的,也就是说有多少事可知的。
但迭代器不是,迭代器不知道要执行多少次,所以可以理解为不知道有多少个元素,每调用一次next(),就会往下走一步,是惰性的。
判断是不是可以迭代,用Iterable
判断是不是迭代器,用Iterator
所以,
凡是可以for循环的,都是Iterable
凡是可以next()的,都是Iterator
集合数据类型如list、truple、dict、str都是Itrable不是Iterator,但可以通过iter()函数获得一个Iterator对象
Python中的for循环就是通过next实现的
== 生成器都是Iterator对象,但是list、dict、str都是迭代对象但是不是迭代器==
使用iter()函数可以把这些可迭代对象转换为迭代器
案例代码:
print("-----------Iter()-------------")
from collections import Iterator
words = [1, 5, 8, 3, 5]
a = isinstance(iter(words), Iterator)
b = isinstance(iter(()), Iterator)
c = isinstance(iter({}), Iterator)
d = isinstance(iter("hhaha"), Iterator)
f = isinstance((x for x in range(5)), Iterator)
print(a)
print(b)
print(c)
print(d)
print(f)
words = iter(words)
print(next(iter(words)))
print(next(iter(words)))
print(next(iter(words)))
运行输出结果:
#
-----------Iter()-------------
True
True
True
True
True
1
5
8
==1.凡是可以作用与for循环对象都是Iterable类型==
==2.可以作用与next()函数的对象都是Iterator类型==
==3.集合数据类型list、tuple、dict、str等是Iterable但不是Iterator==
==4.集合数据类型list、tuple、dict、str等通过iter()可以将其转换为Iterator==
函数定义的格式:
def 函数名():
代码
例如:
#函数的定义
def printInfo():
print("----------")
print("人生苦短,我用python")
print("----------")
#函数的调用
格式:
函数名()
printInfo()
def info():
name = input("请输入你的姓名:")
age = input("请输入您的年龄:")
print("您的姓名为:%s,年龄:%s"%(name,age))
#调用函数
info()
定义函数
def addnum():
a = 33
b = 22
c = a + b
print(c)
调用函数
addnum()
定义函数
def add2Num(a,b):#形参
c = a + b
print(c)
调用函数
add2Num(11,22)#实参
A:形参和实参必须一一对应
B:函数调用时参数的顺序
def test(a,b):
print(a,b)
test(1,2)
test(b = 1, a = 2)
做一做:模拟一个简单的两位数的计算器,功能(加减乘除)
#定义一个函数,完成计算器的加法运算
def add(a,b):
c = a + b
print(c)
# 定义一个函数,完成计算器的减法运算
def minus(a, b):
c = a - b
print(c)
# 定义一个函数,完成计算器的乘法运算
def cheng(a, b):
c = a + b
# print(c)
# 定义一个函数,完成计算器的除法运算
def chu(c, d):
c = c / d
print(c)
add(1,2)
minus(2,1)
cheng(1,2)
chu(1,2)
#定义函数
def add2num(a,b):
c = a + b
return c
#或者
# return a + b
sum = add2num(1,2)
print(sum)
- 保存带有返回值的函数
#定义函数
def add2num(a,b):
c = a + b
return c
#或者
# return a + b
sum = add2num(1,2)
print(sum)
- 函数的类型
函数根据有没有参数,有没有返回值,可以相互组合,一共有4中
无参数,无返回值
无参数,有返回值
有参数,无返回值
有参数,有返回值
此类函数,不能接受参数,也没有返回值,一般情况下,打印提示灯类似的功能,使用该类函数
#无参数,无返回值
def printInfo():
print("------------")
print("人生苦短,我用python")
print("-----------")
printInfo()
此类函数,不能接受参数,但是可以返回某个数据,一般情况,像数据采集,
#无参数,有返回值
def getTemp():
return 24
temp = getTemp()
print("当前的温度为:%d"%temp)
此类函数可以接受参数,但是不可以返回数据,一般情况适用于变量设置数据,而不需要结果
#有参数,无返回值
def add2num(a,b):
result = a + b
print(result)
add2num(11,22)
此类函数,不仅接受参数,同时可以返回某个数据,
"""
1.是否需要传参
是
需要传几个
传一个
2.是否需要返回
有 return 将数据返回,二次处理
没有
"""
def calculateNum(num):
i = 0
sum = 0
while i <= num:
sum += i
i += 1
return sum
result = calculateNum(100)
calculateNum(200)
print(result)
案例2:
#定义一个函数
def get_wendu(a):
wendu = 22
print("当前的温度为:%d"%wendu)
return wendu
def get_wendu_huashi(wendu):
print("======4========")
wendu = wendu + 3
print("=====5=====")
print("当前的温度为:%d"%wendu)
print("======6======")
print("====1======")
result = get_wendu(1000)
print("=======2=======")
get_wendu_huashi(result)
print("=======3======")
def testB():
print("----testB-----")
def testA():
print("-----testA-----")
testB()
testA()
想一想:
案例1:
1.写一个函数打印一条横线(20个“-”)
2.打印自定义行数的横线
分析:
是否参数
需要 传递一个参数 确定“-”号的个数
不需要
是否返回值
需要 返回给调用者
不需要
内容:
打印一条横线
有参 无返回
def test(n):
print(n*"-")
有参 有返回
def test(n):
return n * "-"
无参 无返回
def test():
print(20*"-")
无参 有返回
def test():
retrun "-" * 20
代码:
# n:确定-号的个数
#打印一行-号
def printOneLine(n):
print(n * "-")
# 打印多条横线
def printNumLine(num):
i = 0
while i < num:
printOneLine(20)
i += 1
# 调用函数
printOneLine(20)
printNumLine(3)
具体的细分:
可变对象和不可变对象(值传递,引用传递)
不可变对象
定义:表示该值不能发生变化
不可变的数据类型
String tuple number
"""
String tuple number
"""
def add(num):
num = num + 10
return num
d = 2
e = add(d)
print(d)#2
print(e)#12
def fun(num):
print(id(num))
num = 10
print(id(num))
temp = 20
print(id(temp))
fun(temp)
print(temp)
"""
总结:
在python中,对于不可变对象,调用自身的任意函数,并不会改变对象自身的内容
定义:
值发生改变
可变对象的数据类型有哪些?
list dict set
"""
list dict set
"""
#以列表为例
def change(num):
num.append(1)
d = [0]
change(d)
print(d)
def fun(list):
list[0] = 100
li = [1,2,3,4,5]
fun(li)
print(li)
a = 10
b = 10
b = 40
print(id(a),id(b))
c = 20
d = 30
print(id(c),id(d))
d = c
print(id(c),id(d))
Python允许函数调用时参数顺序和定义时不一致
def myPrint(str,age):
print(str,age)
myPrint("zhangsan","18")
myPrint(age = 18,str = "张三")
**案例2:关键字参数: kw
def person(name,age,**kw):
print("name:",name,"age:",age,"other:",kw)
person("zhangsan","12")
person("zhangsan",12,city = "北京")
person("张三",15,gender = "M",job = "engineer")
概述:
python为了简化函数的调用,提供默认参数机制,调用函数时,缺省参数的值如果没有传入,则会被认为是默认值
#定义一个函数
def printInfo(name,age = 35):
print("name:",name)
print("age:",age)
printInfo("张三")
printInfo(name = "张三")
printInfo(age = 18,name = "haha")
def pow(x ,n = 2):
r = 1
while n > 0:
r *= x
n -= 1
return r
p = pow(2)
print(p)
def printInfo1(name,sex = "nam",age = 35):
print(name,sex,age)
printInfo1("张三","男")
#带有默认值的参数一定要位于参数列表的最后面
#必选参数必须在前面
#设置何种参数为默认值,一般将参数值变化较小的设置为默认参数
概述:
一个函数能够处理比当初声明时更多的参数称为不定长参数,声明时一般不会命名
格式:
def function(args,*args,**kwargs):
加了一个*号的变量args会存放所有未命名的变量参数,相当于 元组
加了**号,存放所有命名的变量参数,相当于表达式 key = value kwargs为字典
print("-" * 20)
# 经典方式
def fun(a, b, *args, **kwargs):
print("a= ", a)
print("b= ", b)
print("args= ", args)
print("kwargs= ", kwargs)
print("*" * 30)
for key, value in kwargs.items():
print(key, "=", value)
fun(1, 2, 3, 4, 5, 6, 6, 8, 9, m=6, n=7, p=8)
# 另一种方式
c = (3, 4, 5)
d = {"m": 6, "n": 7, "p": 8}
print("_" * 50)
fun(1, 2, *c, **d)
print("_" * 50)
# 再一种方式
fun(1, 2, c, d)
def fun1(*args, **kwargs):
print(args)
print(kwargs)
# fun1(1, 2, 3, 4, m=5)
运行输出结果:
--------------------
a= 1
b= 2
args= (3, 4, 5, 6, 6, 8, 9)
kwargs= {'m': 6, 'n': 7, 'p': 8}
******************************
m = 6
n = 7
p = 8
__________________________________________________
a= 1
b= 2
args= (3, 4, 5)
kwargs= {'m': 6, 'n': 7, 'p': 8}
******************************
m = 6
n = 7
p = 8
__________________________________________________
a= 1
b= 2
args= ((3, 4, 5), {'m': 6, 'n': 7, 'p': 8})
kwargs= {}
******************************
匿名函数的基本定义
a = 1
sum = lambda args1,args2:args1 + args2
print(sum(10,20))
特点:
1.lambda只是一个表达式,比函数def声明简单
2.lambda的主体也是一个表达式,而不是代码块,只能在lambda表达式中封装简单的逻辑
3.lambda函数有总计的命名空间,且不能访问自由参数列表以外或者全局命名空间的参数
4.lambda函数能够接受任何数量的参数,只能返回一个表达式的值
作为自定义函数的参数进行传递
匿名函数的应用场景(作为自定义函数的参数进行传递)
def fun(a,b,opt):
print(a)
print(b)
print(opt(10,20))
fun(1,2,lambda x,y:x + y)
作为内置函数的参数
# 第一波
def foo():
print("foo")
# foo#表是函数
foo() # 表示执行foo函数
# 第二波
def foo():
print("foo")
foo = lambda x: x + 1
foo()
是一个闭包,把一个函数当作参数,
返回一个替代的函数,一个本质返回函数的函数
def fun01():
print("fun01")
def fun02(fun):
def fun03():
print("fun03")
fun()
return fun03
f = fun02(fun01)
f()
运行输出结果:
#
fun03
fun01
# 定义基础平台的功能
def f1():
print("f1")
def f2():
print("f2")
def f3():
print("f3")
def f4():
print("f4")
# 业务部门使用基础功能 业务部门第一组
f1()
f2()
f3()
f4()
##业务部门使用基础功能 业务部门第二组
f1()
f2()
f3()
f4()
#老大将任务交给老王同志
def f1():
#验证1
#验证2
#验证3
print("f1")
def f2():
#验证1
#验证2
#验证3
print("f2")
def f3():
#验证1
#验证2
#验证3
print("f3")
def f4():
#验证1
#验证2
#验证3
print("f4")
#业务部门,第一组
f1()
f2()
f3()
f4()
#业务部门,第二组
f1()
f2()
f3()
f4()
#小王
只对基础平台的代码做重构,其他业务部门不动
def check_login():
# 验证1
# 验证2
# 验证3
pass
def f1():
check_login()
print("f1")
def f2():
check_login()
print("f2")
def f3():
check_login()
print("f3")
def f4():
check_login()
print("f4")
#小小王,
#使用装饰器
def w1(func):
def inner():
#验证1
#验证2
#验证3
func()
return inner
@w1
def f1():
print("f1")
@w1
def f2():
print("f2")
@w1
def f3():
print("f3")
@w1
def f4():
print("f4")
将执行完的w1函数的返回值赋值给@w1下面f1,
即及那个w1的返回值重新赋值给f1
"""
# new_f1 = def inner():
# # 验证1
# # 验证2
# # 验证3
# func()
# return inner
#定义一个函数,完成一个包裹的数据
def makeBold(fn):
def wrapped():
return ""+fn()+""
return wrapped
#定义一个函数,完成一个包裹的数据
def makeItalic(fn):
def wrapped():
return ""+fn()+""
return wrapped
@makeBold
def test1():
return "hello world-1"
@makeItalic
def test2():
return "hello world-2"
@makeBold
@makeItalic
def test3():
return "hello world -3"
# print(test1())
# print(test2())
print(test3())
1.引入日志
2.函数的执行时间统计
3.执行函数前的预备处理
4.函数执行后的清理工作
5.权限的校验
6.缓存
from time import ctime, sleep
无参数的函数
def timeFun(func):
def wrapped():
print("%s called at %s" % (func.__name__, ctime()))
func()
return wrapped
@timeFun
def foo():
print("i am foo")
# foo()
# sleep(2)
# foo()
f = timeFun(foo)
f()
#被装饰的函数有参数
def timeFun(func):
def wrapped(a, b):
print("%s called at %s" % (func.__name__, ctime()))
func(a, b)
return wrapped
@timeFun
def foo(a, b):
print(a + b)
foo(3, 5)
sleep(2)
foo(2, 4)
# 3.被修饰的函数有不定长参数
def timeFun(func):
def wrapped(*args, **kwargs):
print("%s called at %s" % (func.__name__, ctime()))
func(*args, **kwargs)
return wrapped
@timeFun
def foo(a, b, c):
print(a + b + c)
foo(3, 5, 7)
#装饰器中的return
def timeFun(func):
def wrapped():
print("%s called at %s" % (func.__name__, ctime()))
func()
return wrapped
@timeFun
def foo():
print("i am foo")
@timeFun
def getInfo():
return "---haha----"
foo()
print(getInfo())
* 函数在执行时,要带上所有必须的参数进行调用,但是有时参数可以在函数被调用之前提前获知
* 好处: 一个函数或者多个函数的参数预先就能用上,一边函数能用更少的参数进行调用
from functools import partial
def add(a, b):
return a + b
add(3, 5) # 8
add(4, 7) # 11
puls = partial(add, 100)
result = puls(10)
print(result)
运行输出结果:
#
110
# 进制转换
# 案例:
import functools
print(int("1010", base=2), "--> base表示进制")
# 偏函数
def int2(str, base=2): # int(x,base)x-->字符串或者数字 base---》进制数 默认是十进制
return int(str, base)
print(int2("1011"))
int3 = functools.partial(int, base=2)
print(int3("111"))
在这里偏函数表达式的意思就是:
* 在函数add的调用时,我们已经知道里面其中一个参数,我们通过这个参数,
* 重新绑定一个函数partial(add,100),然后再去调用
第一个案例(回调函数无返回值):
def clear1(times):
"""
模拟宾馆扫地
:param times:
:return: None
"""
print("完成扫地的次数", str(times))
def clear2(times):
"""
模拟宾馆洒水
:param times:
:return: None
"""
print("洒水的次数", str(times))
def call_clear(times, function_name):
"""
相当于控制器,控制方法的调用,实现回调函数的核心
:param times: 调用函数次数
:param function_name: 回调函数名称
:return: 调用函数的结果
"""
return function_name(times)
#函数外部
call_clear(10, clear1)
第二个案例(回调函数有返回值):
"""
生成偶数
1.生成一个2 * K形式的偶数
2.生成一个4 * K形式的偶数
"""
# 回调函数1
def double_2k(x):
return 2 * x
# 回调函数2
def double_4k(x):
return 4 * x
# 控制器
def get_number(k, get_even_number):
"""
:param k: 传入的基数
:param get_even_number: 回调函数名称
:return: 回调返回值
"""
return get_even_number(k) + 1
def main():
k = 2
i01 = get_number(k, double_2k)
i02 = get_number(k, double_4k)
i03 = get_number(k, lambda x: x * 8)
print(i01)
print(i02)
print(i03)
main()
定义:
在函数中不调用其他函数,而是调用自己------》递归函数(自己玩自己)
凡是循环能做的事,递归都能做
#形式:
def show():
print("我叫王二小")
show()
show()
"""
例如:
计算一个阶乘n!
n! = 1*2*3*4...*n
1! = 1
2! = 2*1 2*1!
3! = 3*2*1 3*2!
4! = 4*3*2*1 4*3!
n! = n*(n-1)!
参数
要 1个
返回值
要 结果
#方法1
def calnum(num):
# for temp in range(1,num+1):
i = 1
result = 1
while i <= num:
# result = result * i
result *= i
i += 1
return result
ret = calnum(3)
print(ret)
#方法2:
def calnum(num):
if num >=1:
result = num*calnum(num-1)
else:
result = 1
return result
ret = calnum(3)
print(ret)
注意:防止死循环(递归)
import os
def getAllDirRE(path,sp = ""):
#得到当前目录下的所有的文件
filesList = os.listdir(path)
#处理每一个文件
sp += " "
for fileName in filesList:
#判断是否是路径(用绝对路径)
fileAbsPath = os.path.join(path,fileName)
if os.path.isdir(fileAbsPath):
print(sp+"目录:",fileName)
#递归函数
getAllDirRE(fileAbsPath,sp)
else:
print(sp + "普通文件",fileName)
getAllDirRE(r"G:\1806")
模拟栈存储方式获取指定路径下所有文件
栈定义:
又名堆栈
堆栈=列表+函数:
.append()#入栈
.pop() #出栈
#入栈
stack = []
stack.append("A")
print(stack)
stack.append("B")
print(stack)
stack.append("C")
print(stack)
#出栈
res1 = stack.pop()
print("res1=",res1)
print(stack)
res2 = stack.pop()
print("res1=",res2)
print(stack)
def getAllDirRE(path):
import os
stack = []
stack.append(path)
#处理栈,当栈为空的时候结束当前动作
while len(stack) != 0:
#从栈中取数据
dirPath = stack.pop()
filesList = os.listdir(dirPath)
#得到的数据,如果是普通的文件,直接打印,如果,是目录继续压栈
for fileName in filesList:
fileAbsPath = os.path.join(dirPath,fileName)
if os.path.isdir(fileAbsPath):
print("目录"+fileName)
#压栈
stack.append(fileAbsPath)
else:
print("普通"+fileName)
getAllDirRE(r"G:\1806")
模拟队列获取指定路径下所有文件
先进先出 排队
collections
append:添加
queue:获取队列
len:获取长度
popleft:出队
listdir:获取当前目录的所有文件
isdir :判断是否是文件
import os
import collections
def getAllDirQu(path):
#创建一个队列
queue = collections.deque()
#进队
queue.append(path)
while len(queue) != 0:
#出队
dirPath = queue.popleft()
#获取当前路径下的所有的文件
filesList = os.listdir(dirPath)
for fileName in filesList:
#绝对路径
fileAbsPath = os.path.join(dirPath,fileName)
#判断是否是目录(文件夹),如果是进队,不是直接打印
if os.path.isdir(fileAbsPath):
print("目录:"+fileName)
queue.append(fileAbsPath)
else:
print("普通文件"+fileName)
getAllDirQu(r"G:\1806")
优点:
1.提高代码的可维护性
2.提高代码的复用性,当一个模块定义完毕,可以被多个地方引用
3.引用其他的模块(内置模块,第三方模块)
注意:
避免函数名和变量名的冲突
在python中用关键字import来引入模块,一般放在代码最前面
格式:
import module1,module2....
当解释器遇到import 语句,如果模块在当前的搜索路径就会被导入
模块调用函数的基本格式:
模块名.函数名()
思考:
为什么必须加上模块名才能调用?
在多个模块中含有同名的函数,此时如果只是通过函数名来进行调用,解释器就无法知道到底需要调用哪个函数
如果使用import导入模块,在调用的时候必须加上模块名
import math
print(sqrt(2))#错误的
print(math.sqrt(2))
使用from…import……导入模块的一部分
只需要用到模块中的某一个函数,此时只需要引入该函数即可,无需引入模块中的所有函数,浪费内存
格式:
from 模块名 import 函数名1,函数名2…
案例:
from math import sin,cos
math.sin()#报错 math未定义
sin()
cos()
sqrt()#报错 未导入sqrt函数
思考:
如果想要引入一个math模块中所有的函数
from math import *
使用from…import * 导入模块所有的内容
from...import*:
把一个模块中所有的内容导入到当前的命名空间
格式:
from module import *
as 理解为重命名,将原有的名称替换成一个新的名字
作用:
有时候导入的模块的名字很长或者很难记住简洁
格式:
import modName as newName
import math as aa(#aa表示math)
import math as aa
math#报错
aa.sin()
aa.ceil()
注意:如果使用as将原有的模块名重命名,原先的将不可用
当你导入一个模块,python的解释器对模块位置的搜索的顺序:
* 当前目录
* 如果不再当前的目录,python则搜索在shell变量的PYTHONPATH的每一个目录
* 模块的搜索路径存储在system模块的sys.path模块中变量,变量中包含当前的目录,
python path和由安装过程决定的默认的目录
pythonpath 变量----》环境变量
有些时候,Python自带的模块不能很好的解决我们遇到的问题,我们需要自定义一些具有独特功能的模块来完成代码的编写
"""
求和函数
需要传递两个参数:
a:int
b : int
返回a+b的和的结果
"""
def add(a,b):
return a + b
import test
test.add(1,2)
"""
求和函数
需要传递两个参数:
a:int
b : int
返回a+b的和的结果
"""
def add(a,b):
return a - b
ret = add(1,-0)
print(ret)
为了解决测试的问题,python在执行一个文件时有个变量__name__
如果直接在test.py模块中可以将print进行修改
print()
if __name__ == "__main__":
执行语句
方式1:
使用import关键字导入
格式:
import 文件.模块
import day09.test
# day09.test.add(1,2)
day09.test.add(1,2)
方式2:
使用from 文件夹 import 模块
格式:
from 文件夹的名字 import 文件名
from day09 import test
test.add(1,2)
包使用总结:
总结:
包将有联系的模块组织在一起,放到同一个文件夹下,
在创建文件夹的时候会自动创建一个__init__.py文件,======》包
想一想
1. __init__.py文件有什么用?
__init__.py控制着包的导入的行为
2.__init__.py文件为空?
仅仅是把包导入,不会导入该包中的模块
pip的安装:
pip的安装:
1.到https://pypi.python.org/pypi/pip 下载pip版本tar.gz,下载完成直接到本地解压
2.在DOS命令行进入pip解压的目录,输入python setup.py install进行安装
3.如果安装完成 提示finished
4.如果出现问题提示pip没有找到该命令,可以将python/Script目录配置到path环境变量中
安装PTL
1、time
import time
2、datetime
import datetime
3、calendar
import calendar
时间戳(timestamp):
时间戳表示的是从1970年1月1日00:00:00,按秒计算偏移量
clock(),time()
print(type(time.time())) #返回的是float
print(time.time())
print(time.clock())
%a 本地简化的星期的名称
%A 完整的星期的名称
%b 简化的月份的名称
%B 完整的月份的名称
%c 本地对应的日期表示和时间表示
%d 月内中的天数(0~31)
%H 24小时制小时数(0~23)
%m 月份(01~12)
%M 分钟数(00~59)
%w 星期(0~6) 星期天开始
元组:共有9中元素,返回的是struct_time的函数主要有gmtime(),localtime(),strptime()
索引 属性 值
0 tm_year(年) 2018
1 tm_mon(月) 1~12
2 tm_mday(日) 0~31
3 tm_hour(时) 0~23
4 tm_min(分钟) 0~59
5 tm_sec(秒) 0~61
6 tm_wday(weekday) 0~6(0表示周日)
7 tm_yday(一年中的第几天) 1~366
8 tm_isdst(是否是夏令时) 默认为-1
UTC :世界协调时间 格林威治天文时间 世界标准时间
在中国UTC+8
#localtime():获取当前时间,返回struct_time格式返回
#获取当前的时间
# print(time.localtime())
# 获取当天的时间
print(datetime.datetime.now())
# 当前的日期
print(datetime.date.today())
# 获取昨天的时间
def getYesterday():
today = datetime.date.today()
oneday = datetime.timedelta(days=1)
yesterday = today - oneday
print(type(today))
print(type(yesterday))
return yesterday
yesterday = getYesterday()
print(yesterday)
#获取日历相关的信息
#获取某个月的日历
# 格式:calendar.month(x,y)x:显示的年份,y
# 显示的月份
cal = calendar.month(2015,12)
print(cal)
#设置日历的第一天
calendar.setfirstweekday(calendar.SUNDAY)
cal = calendar.month(2015,12)
print(cal)
#获取某一年的日历:
cal = calendar.calendar(2015)#参数为具体的年份
print(cal)
cal = calendar.HTMLCalendar(calendar.MONDAY)
print(cal.formatmonth(2015,12))
思考:
请用程序描述如下事件:
A同学报道等级信息
B同学报道等级信息
C同学报道等级信息
A同学做自我介绍
B同学自我介绍
c同学自我介绍
"""
请用程序描述如下事件:
A同学报道等级信息
B同学报道等级信息
C同学报道等级信息
A同学做自我介绍
B同学自我介绍
c同学自我介绍
"""
stu_a = {"name":"A","age":21}
stu_b = {"name":"B","age":22}
stu_c = {"name":"C","age":23}
def stu_infor(stu):
for key,value in stu.items():
print("key = %s,value = %d"%(key,value))
"""
根据业务逻辑从上到下写代码
将数据与函数绑定到一起,进行封装,能够更快速的开发程序,减少代码的重写的过程
def 发送邮件(内容):
# 连接邮箱服务器
# 发送邮件
# 关闭连接
对象是面向对象思想的核心
在使用对象的过程中,为了将具有共同特征和行为的一组对象抽象定义-----》类
类---》制造飞机的图纸
用它来创建的飞机就相当于对象
具有相似的内部状态和运动规律的实体的集合(抽象)
或者具有相同的属性和行为的统称
定义:
类 抽象的 在使用的时候通常会找到这个类的具体的存在----》对象
特点:
使用这个具体的存在,一个类可以找到多个对象
概述:
某一个具体事物的存在,在现实世界中可以看得见摸得着
可以直接使用
总结:
类和对象之间的关系:
就像利用玩具模型来创建多种不同的玩具
类就是创建对象的模板
奔驰汽车 类
奔驰smart 类
张三的那辆奔驰smart 对象
狗 类
大黄狗 类
李四家的那只大黄狗 对象
水果 类
苹果 类
红苹果 类 红富士苹果 类
张三嘴里吃了一半的苹果 对象
类(class):由3部分组成
类的名称:类名
类的属性:一组数据
类的方法:允许对其操作的方法(行为)
"""
事物的名称(类名):人(Person)
属性:身高 年龄
方法(行为):跑,吃饭
"""
"""
狗 类
类名:dog
属性:品种,毛色,性别,腿的数量
方法:叫,跑,咬人,摇尾巴
"""
如何把日常生活中的事物抽象成程序中的类?
类:
拥有相同属性和行为的对象可以抽取出来-----》类
一般名称提炼法
例如:
1.坦克发射了3颗炮弹炸掉了2架飞机
坦克----》抽象成类
炮弹---》抽象成类
飞机----》抽象成类
2.小明在公车上牵了一条叼着热狗的狗
小明 -----》 人类
公车 -----》 交通工具类
热狗 -----》 食物类
狗 -----》 狗类
游戏中的类和对象
cf
人
枪
植物大战僵尸:
向日葵 -----》类
类名:xrk
属性:颜色,尺寸
行为:产生阳光
豌豆: ------》 类
类名: wd
属性:颜色,发型
行为:发射炮弹
僵尸:
类名:js
属性:颜色,
行为:走,吃植物,啃
class 类名:
属性1
属性2
属性3
... ...
方法1
方法2
方法3
... ...
"""
猫:
类名:cat
属性:毛色,性别
行为:跑,吃
"""
class Cat:
#属性
#方法
def eat(self):
print("猫吃鱼....")
def drink(self):
print("猫喝可乐....")
"""
车:
类名:Car
属性:颜色,
行为:跑
"""
class Car:
#方法列表
def getCarInfo(self):
print("车的轮子数:%d,颜色%s"%())
def move(self):
print("车子在移动....")
* Python3.X之后对类的定义方式进行了改变
* 在类名后面(object),Car(object)
注意:
定义类名时,尽量使用大驼峰命名法则
python中,可以根据已经定义好的类来创建一个一个的对象
#创建一个Car类
class Car(object):
def move(self):
print("车子在移动....")
def toot(self):
print("车子在鸣笛....")
#创建车子的对象,并用变量进行保存
BMW = Car()
BMW.color = "黑色"#车子的颜色
BMW.wheelNum = 4#车轮的数量
BMW.color = "白色"
BMW.move()
BMW.toot()
print(BMW.color)
print(BMW.wheelNum)
BMW = Car():这样就产生了一个Car的实例对象,
此时可以通过实例对象BMW访问属性和行为
BMW--->对象,它拥有属性和行为
下面以Cat类为例子,添加属性
class Cat:
def eat(self):
print("猫在吃鱼.....")
def drink(self):
print("猫在和芬达....")
创建一个Cat对象
tom = Cat()
调用tom指向的对象中的方法
tom.eat()
tom.drink()
tom.name = "汤姆"
tom.age = 3
class Cat:
def eat(self):
print("猫在吃鱼.....")
def drink(self):
print("猫在和芬达....")
#创建一个Cat对象
tom = Cat()
#调用tom指向的对象中的方法
tom.eat()
tom.drink()
tom.name = "汤姆"
tom.age = 3
print("tom的中文名:%s,年龄:%d"%(tom.name,tom.age))
init方法是初始化函数,用来完成一些对象默认的设置
init方法格式
class 类名:
#初始化函数,用来完成一些默认的设置
def __init__(self):
函数体语句
init()方法调用
下面以汽车类Car示例init方法的调用
class Car:
# 初始化方法
def __init__(self):
self.color = "黑色"
self.wheelNum = 4
# 普通的方法,移动
def move(self):
print("车子在移动.....")
bmw = Car()
print(“车子的颜色:%s” % bmw.color)
print(“车子的轮子数:%d” % bmw.wheelNum)
bmw1 = Car()
print(“车子的颜色:%s” % bmw1.color)
print(“车子的轮子数:%d” % bmw1.wheelNum)
总结:
当创建Car对象后,在没有调用__init__()函数的前提下,
bmw就默认拥有了两个属性color/wheelNum,
原因是__init__()函数在创建对象后,就立刻默认被调用
还有另一种方式能更灵活的使用init方法
第二种方式
class Car:
#初始化方法
def __init__(self,newWheelNum,newColor):
self.wheelNum = newWheelNum
self.color = newColor
#普通的方法,移动
def move(self):
print("车子在移动.....")
#创建对象
bmw = Car(4,"黄色")
print("车子的颜色:%s"%bmw.color)
print("车子的轮子数:%d"%bmw.wheelNum)
bmw1 = Car(6,"绿色")
print("车子的颜色:%s"%bmw1.color)
print("车子的轮子数:%d"%bmw1.wheelNum)
总结:
init():在创建一个对象的时候默认被调用,不需要手动调用
init(self),默认一个参数名字为self,不需要开发者传递
python 解释器会自动将当前的对象的引用传递进来
分析下面案例
import sys
class Cat(object):
def __init__(self):
self.color = "while"
self.weight = "8斤"
def __del__(self):
print("所有对象被干掉啦")
def __str__(self):
return ("颜色%s-体重%s" % (self.color, self.weight))
Tom01 = Cat()
print("Tom01即将被干掉,当前Tom01引用指向地址被引用数量%s" % sys.getrefcount(Tom01))
Tom02 = Tom01
Tom03 = Tom02
print(Tom01)
print(Tom02)
print(Tom03)
print("Tom01即将被干掉,当前Tom01引用指向地址被引用数量%s" % sys.getrefcount(Cat))
print(id(Cat))
del Tom01
print("Tom02即将被干掉,当前Tom02引用指向地址被引用数量%s" % sys.getrefcount(Tom02))
print("Tom02即将被干掉,当前Tom03引用指向地址被引用数量%s" % sys.getrefcount(Tom03))
print("Tom02和Tom03引用指向地址是相同的吗?", Tom02 == Tom03)
del Tom02
print("Tom02被干掉啦")
# del Tom03
# print("Tom03被干掉啦")
print("我是程序结尾的一句话")
print("-" * 30)
print(Tom03)
print(repr(Tom03))
print(eval(repr(Tom03)))
总结:
==同一个类可以创建多个对象,==比如常见的猫有加菲和Tom
class Cat:
def eat(self):
print("猫吃鱼....")
def drink(self):
print("猫喝水....")
#创建tom 对象
tom = Cat()
tom.eat()
tom.drink()
#给tom指向的对象添加两个属性
tom.name = "汤姆"
tom.age = 2
jiafei = Cat()
jiafei.eat()
jiafei.drink()
jiafei.name = "加菲"
jiafei.age = 3
同意个类创建的多个对象是相互独立的
魔方方法:
定义类
class Car:
def __init__(self,newWheelNum,newColor):
self.wheelNum = newWheelNum
self.color = newColor
def __str__(self):
msg = "嘿嘿....我的颜色是"+self.color+"我有"+self.wheelNum+"个轮子"
return msg
def move(self):
print("车子在移动....")
创建一个对象
bmw = Car("4","白色")
print(bmw)
总结:
在python中方法名如果是__XXX__那么就具有特殊的功能,—》魔方
str():
当使用print输出对象,只要定义了__str__()方法,
那么就会返回这个方法中return 的数据
str():在调用print打印对象的时候自动调用,给用户用的,是一个描述对象的方法
repr():给机器用的,供python的解释器读取
注意:
在没有__str__()函数时,有__repr__(),str == repr
import datetime
now = datetime.datetime.now()
print(str(now))
print(repr(now))
print(eval(repr(now)))
datetime python的内置模块,import 加载导入模块
now = datetime.datetime.now()系统当前的时间赋值给now变量
eval函数是把参数当做代码执行,验证repr之后的字符串可以被python识别执行
class Person(object):
def __init__(self,name,age,height,weight):
self.name = name
self.age = age
self.height = height
self.weight = weight
def __str__(self):
return "%s-%d-%d-%d"%(self.name,self.age,self.height,self.weight)
#创建人的对象
per = Person("hanmeimei",20,170,55)
print(per)
print(repr(per))
# print(eval(repr(per)))#eval函数中的参数为一个字符串,如果不是一个字符串会报错
aa = "hello"
print(repr(aa))
print(eval(repr(aa)))
当一个对象的属性过多,并且还要打印,重写__str__()方法简化代码的书写
可读性强
repr()函数得到的字符串,通常可以用来获得该对象,obj == eval(repr(obj))这个等式是成立的
返回的是一个字符串
定义:
构造方法类似__init__()函数,差别在于一个对象被构建好之后会自定调用该方法
python中创建一个构造方法(使用__init__())
class Cat:
def init(self):
初始化属性
重写对于类很重要:
尤其对于构造 init
class Bird():
def __init__(self):
self.hungry = True
def eat(self):
if self.hungry:
print(".....")
self.hungry = False
else:
print("no thanks")
b = Bird()
b.eat()
b.eat()
在子类中定义了一个和父类同名的函数—》重写
#定义一个类
class Animal:
def __init__(self,name):
self.name = name
def printName(self):
print("名字为:%s"%self.name)
#定义一个函数
def myPrint(animal):
animal.printName()
#创建对象
dog1 = Animal("西西")
myPrint(dog1)
dog2 = Animal("北北")
myPrint(dog2)
- 总结:
* 所谓self理解为自己,也就是对象自身
* 程序中的self是什么?哪个对象调用了__init__(),self就代表谁
"""
烤牛排:
类:
类名:
牛排:
属性:
几成熟
0--3表示生的,4--6表示半生不熟,7--9表示熟了,10及以上表示糊了
红酒
胡椒
... ...
行为:
烧烤时间
添加佐料
__init__()
__str__()
"""
class CookSteak:
def __init__(self):
self.time = 0
self.cook_level = 0
self.cook_string = "生的"
self.condiments = []
def cook(self, time):
self.cook_level += time
if self.cook_level > 9:
self.cook_string = "扔了吧,都糊啦"
elif self.cook_level > 6:
self.cook_string = "熟了,味道应该很棒"
elif self.cook_level > 3:
self.cook_string = "半生不熟,快要熟了"
elif self.cook_level > 0:
self.cook_string = "牛排刚放进去,耐性等一会"
else:
print("没有这个状态")
print("牛排已经烤了很久了,现在达到%s成熟了," % self.cook_level)
def add_cendiments(self, cendiments):
self.condiments.append(cendiments)
def __str__(self):
return "牛排已经烤了很久了,现在达到%s成熟了,添加的佐料有%s" % (self.cook_level, self.condiments)
hui_ling_dun = CookSteak()
hui_ling_dun.cook(1)
hui_ling_dun.cook(1)
hui_ling_dun.cook(1)
hui_ling_dun.cook(1)
hui_ling_dun.add_cendiments("胡椒粉")
hui_ling_dun.cook(1)
hui_ling_dun.cook(1)
hui_ling_dun.add_cendiments("红酒")
hui_ling_dun.cook(1)
print(hui_ling_dun)
如果有一个对象,当需要对其进行修改属性:
方法2种
直接修改 对象名.属性名 = 数据
间接修改 对象名.方法名()
将属性定义为私有
格式:
__属性名
# 定义一个类
class Person(object):
def __init__(self, name):
self.__name = name
def __str__(self):
return self.__name
def getName(self):
return self.__name
def setName(self, newName):
if len(newName) <= 5:
self.__name = newName
else:
print("名字的长度需要小于等于5")
person = Person("张三")
# print(person)
# #直接修改 对象名.属性名 = 数据
# person.__name = "李四"
# print(person)
# 间接访问 对象名.属性名
# print(person.__name) #报错
person.setName("李四")
print(person.getName())
person.setName("王五")
print(person.getName())
class Person(object):
def __init__(self,name,age,height,weight,money):
self.name = name
self.__age__ = age
self.height = height
self.weight = weight
self.__money = money
def ss(self):
print(self.__money)
#通过内部的方法,去修改私有属性
#通过自定义的方法实现对私有属性的修改
def getMoney(self):
return self.__money
def setMoney(self,money):
#数据的过滤
if money < 0:
money = 0
self.__money = money
#创建对象
person = Person("张三",12,170,55,100)
# person.age = 15
# person.setMoney(200)
# print(person.getMoney())
# print(person.__money)#外部使用 不ok
print(person.ss)#内部 ok
思考,不能通过对象访问私有属性?
在python的解释器把__money 变成_Person_money.
任然可以使用_Person_money去访问,但是不建议这么做,
"""
person._Person__money = 1
print(person.getMoney())
print(person.__age__)
"""
在python中__XXX__,属于特殊的变量,可以直接访问(公有)
"""
继承的概念:
程序中的继承:
继承描述的是事物之间的所属关系,之前的猫,狗----》动物
程序中可以描述猫和狗继承动物
object
动物
猫 狗
加菲 波斯 金毛 二哈
# 定义一个父类
class Cat(object):
def __init__(self, name, color):
self.__name = name
self.color = color
def run(self):
print("%s----在跑" % self.__name)
# 定义一个子类
class Bosi(Cat):
def setNewName(self, newName):
self.__name = newName
def eat(self):
# print("%s---在吃饭"%self.__name)
pass
bs = Bosi("波斯", "白色")
# print(bs.__name)
print(bs.color)
bs.eat()
bs.setNewName("加菲")
bs.eat()
bs.run()
说明:
虽然在子类中没有定义__init__()方法
但是父类有,在子类继承父类的时候这个方法也就被继承过来
创建Bosi对象,默认执行那个继承过来的__init__方法
总结:
子类在继承的时候,在定义类的时候,小括号中为父类的名字
父类的公有属性和公有方法会被子类继承
print("父类中出现私有的情况")
# 定义一个父类
class Animal(object):
def __init__(self, name="动物", color="白色"):
self.__name = name
self.color = color
def __test(self):
print(self.__name)
print(self.color)
def test(self):
print(self.__name)
print(self.color)
# 定义一个子类
class Dog(Animal):
def Test1(self):
# print(self.__name)#不能访问父类的私有属性
print(self.color)
def dogTest2(self):
# self.__test()#不能访问父类的私有方法
self.test()
a = Animal()
# print(a.__name)#报错,不能通过对象访问私有属性
# a.__test()#报错,不能访问私有方法
a.test()
print("--------")
d = Dog(name="小花狗", color="黄色")
print(d.color)
d.Test1()
d.dogTest2()
总结:
私有的属性,不能通过对象直接访问,可以通过方法进行访问
私有方法,不能通过对象直接访问
私有属性,方法都不会被子类继承,也不能被访问
子类继承的是父类公有是属性和方法
生活中的例子:
程序中的多继承:
class A:
def printA(self):
print("----A-----")
# 定义一个父类
class B:
def printB(self):
print("----B-----")
# 多继承
class C(A, B):
def printC(self):
print("----C-----")
# 创建C的对象
c = C()
c.printA()
c.printB()
c.printC()
说明:
python中可以多继承
父类中的方法和属性,子类会继承
print("多个父类中出现相同的方法")
# 如果父类A和B,有一个同名的方法,
# 那么子类在调用方法的时候,执行哪个父类中的方法
# 定义一个父类
class A:
def printA(self):
print("----A-----")
# 定义一个父类
class B:
def printA(self):
print("----B-----")
# 多继承
class C(A, B):
pass
c = C()
c.printA()
print(c)
# 案例:
class base(object):
def test(self):
print("base--test")
class D(base):
def test(self):
print("D----test")
class E(base):
def test(self):
print("E----test")
class F(D, E):
pass
f = F()
f.test()
print(F.__mro__) # 可以查看类的对象搜索方法时的先后顺序
练习:
有一个学校,人数为0,入职的老师和学生,人数增加1,
老师要显示姓名和工号,学生要显示姓名和成绩
使用继承
父类 学校
子类 老师 学生
print("练习题")
# 学校类
class School:
# 定义默认的人数为0
schoolNum = 0
# 初始化数据
def __init__(self, name):
self.name = name
School.schoolNum += 1
print("学校新加入的成员:%s" % self.name)
print("学校现有的学生的人数%s" % School.schoolNum)
# 自我介绍,姓名和工号,成绩
def sayHello(self):
print("我叫%s" % self.name)
# 创建老师类
class Teacher(School):
def __init__(self, name, id):
a = School(name)
self.name = name
self.id = id
def sayHello(self):
print("我叫%s,工号为%d" % (self.name, self.id))
# 学生类
class Student(School):
def __init__(self, name, result):
self.name = name
self.result = result
b = School(name)
def sayHello(self):
print("我叫%s,成绩:%d" % (self.name, self.result))
# 创建老师对象
t = Teacher("小明", 1000)
t.sayHello()
s = Student("张三", 99)
s.sayHello()
#定义一个父类
class Cat(object):
def sayHello(self):
print("hello----1")
#定义子类
class Bosi(Cat):
def sayHello(self):
print("hello -------2")
#创建子类的对象
bs = Bosi()
bs.sayHello()
想一想:要求打印出hello ------1,该如何实现
class Cat(object):
def __init__(self, name):
self.name = name
self.color = "yello"
class Bosi(Cat):
def __init__(self, name):
self.name = name
# 方式1调用父类__init__方法,python2中/python3中
# Cat.__init__(self,name)
# 方式2:super(),可以完成对父类__init__()的调用
# super(Bosi,self).__init__(name)
# 方式3:super()直接调用__init__()函数
super().__init__(name)
# super()#一层一层向上
bosi = Bosi("xiaoming")
print(bosi.name)
print(bosi.color)
Python多态案例:
class F1(object):
def show(self):
print("F1.show")
class S1(F1):
def show(self):
print("S1.show")
class S2(F1):
def show(self):
# super().show()
print("s2.show")
# F1.show(self)
# super(S2,self).show()
# python 动态的言语
def func(F1):
print("func接受一个数据类型")
# print(F1.show())
# func(F1)
# s1 = S1()
# s1.show()
s2 = S2()
s2.show()
概述:
类属性就是类对象所拥有的属性,它被所有类对象的实例对象所公有
类属性在内存中只存一个副本对于公有类属性和实例属性在类的外面可以直接被访问
类属性:
定义一个类:
class People(object):
name = "xiaoming" # 公有的属性
__age = 12 # 私有属性
# 创建People类的对象
p = People()
print(p.name) # ok
print(People.name) # ok
# print(p.__age) #no ok 不能在类外面通过实例对象访问类的私有属性
print(People.__age) # no ok 不能通过类对象访问私有属性
# 定义类
class People(object):
address = "北京"
def __init__(self):
self.name = "xiaoming" # 实例属性
self.age = 12 # 实例属性
p = People()
p.age = 20
print(p.age)
print(p.name)
print(p.address)
print(People.address)
# print(People.name) #类对象访问实例属性
# print(People.age) #类对象访问实例属性
print("@" * 20)
class People(object):
country = "china"
def __init__(self):
self.name = "hhaa"
print(People.country)
p = People()
print(p.country)
p.country = "chinese" # 实例属性会屏蔽同名的类属性
print(p.country)
print(People.country)
del p.country
print(p.country)
如果需要在类外修改类属性,必须通过类对象去引用再进行修改
如果通过实例对象去引用,会产生一个同名的实例属性,
这个方式其实是修改实例属性,不会影响类属性,
并且之后如果需要通过实例对象去引用该同名的属性,
实例属性会强制屏蔽类属性,即引用的是类属性,除非删除该实例属性
类方法:
类对象所拥有的方法,需要使用到修饰器 @classmethod---->类方法
对于类方法,第一个参数必须是类对象,一般以cls表示作为第一个参数
(当然可以用其他的名字,但是不建议修改)
class People(object):
country = "china"
@classmethod
def getCountry(cls):
return cls.country
p = People()
print(p.country)
print(p.getCountry()) #通过实例对象进行访问
print(People.country)
print(People.getCountry()) # 通过类对象去引用
print("#" * 20)
class People(object):
country = "china"
# 类方法
@classmethod
def getCountry(cls):
return cls.country
@classmethod
def setCountry(cls, country):
cls.country = country
p = People()
print(p.getCountry()) # 可以用实例对象引用
print(People.getCountry()) # 通过类对象的的引用
p.setCountry("chinese")
print(p.getCountry())
print(People.getCountry())
print("#" * 20)
class People(object):
country = "china"
# def getCountry(self):
# return " "
@staticmethod
def getCountry():
return People.country
print(People.getCountry())
p = People()
print(p.getCountry())
从类方法和实例方法(普通方法)和静态方法
类方法第一个参数是类对象cls,那么通过cls的引用必定是类对象的属性和方法
实例方法第一个参数self,自身,那么通过self引用的可能是类属性,也可以是实例属性(具体分析)
问题?
如果出现相同名称的类属性和实例属性
实例属性优先级更高
静态方法:静态方法中不需要传递任何参数(额外的定义参数),
在静态方法中的引用是类属性,必须通过类对象来引用
print("*" * 30)
import types
class Person(object):
def __init__(self, name=None, age=None):
self.name = name
self.age = age
def eat(self):
print("吃饭....")
def run(self, speed):
print("%s在移动,速度%s" % (self.name, speed))
P = Person("小王","24")
# P.run("220")
P.run = types.MethodType(run,P)#第一个参数L:需要添加的方法,参数二:添加到该类的实例对象
P.run("100")
运行结果:
******************************
小王在移动,速度100
python中的类,类同样也是一种对象,只要使用关键字class
python解释器在执行的时候会创建一个对象
class Test(object):
pass
test = Test()
print(test)#结果为类创建对象在内存中的地址
判断一个对象是否在某个类中–hasattr(obj,str)
class Test(object):
pass
test = Test()
print(test)
print(Test)
def info(o):
print(o)
#可以将类作为参数传递函数
info(test)
#可以为类添加新的的属性
print(hasattr(Test,"new_attribute"))
Test.new_attribute = "haha"
print(hasattr(Test,"new_attribute"))
print(Test.new_attribute)
#将一个类赋值给一个变量
test1 = Test
print(test1)
def choose_name(name):
if name == "haha":
class haha(object):
pass
return haha
else:
class heihei(object):
pass
return heihei
myClass = choose_name("haha")
print(myClass)#函数返回的haha ---> 类,不是类的实例
print(myClass())#返回类创建的实例,也是对象
python中的内联函数type()
print(type(1))
print(type("1"))
print(type(choose_name("haha")))#类的类型 返回值-->type
type创建类案例:
Test01 = type("Test01", (), {})
print(Test01)
print(Test01())
输出结果:
<__main__.Test00 object at 0x000001360A04C160>
结果:显示和我们学习的类具有一样类型的内存地址
type创建有内容的类
Test01 = type("Test01", (), {"name": "hello", "age": 18})
print(Test01)
print(Test01())
print(Test01().name)
print(Test01().age)
输出结果:
<__main__.Test01 object at 0x0000025B5773B860>
hello
18
Test01 = type("Test01", (), {"name": "hello", "age": 18})
print(Test01)
print(Test01())
print(Test01().name)
print(Test01().age)
Test02 = type("Test02", (Test01,), {})
print(Test02)
print(Test02())
print(Test02.__mro__)
输出结果:
<__main__.Test02 object at 0x000002BBD33FBA58>
(, , )
注意:
type函数中有三个参数,字符串是类名,元祖中是父类的名字,字典中添加属性
添加的属性是类属性,不是实例属性
添加的方法可以使普通方法,静态方法,类方法
1,添加实例方法
Test01 = type("Test01", (), {"name": "hello", "age": 18})
print(Test01)
print(Test01())
print(Test01().name)
print(Test01().age)
def test(self):
print("haha")
Test02 = type("Test02", (Test01,), {"test": test})
print(Test02)
print(Test02())
print(Test02().test)
# demo02 = Test02().
Test02().test()
print(Test02.__mro__)
1,添加静态方法
@staticmethod
def test03():
print("hahaha--test03")
return "test03"
Test003 = type("Test003", (Test01,), {"test03": test03})
print(Test003)
print(Test003().test03())
2,添加类方法
@classmethod
def test04(cls):
print("hahaha--test04")
return "test04"
Test004 = type("Test004", (Test01,), {"test04": test04})
print(Test004)
print(Test004().test04())
总结:
元类是创建类所需要的事物,你创建类就是为了创建类的实例对象
python中类也是对象
元类:就是用来创建这些类(对象)的类----》元类
myclass = myclass()#使用元类长创建一个对象,这个对象称之为类
myobject = myclass()#使用类创建畜类的实例对象
type实际上就是一个元类,是python在幕后创建所有类的元类
class可以查看元素、对象所属的类,功能和type相似
print("-" * 30)
age = 35
print(age.__class__)
name = "zhangsan"
print(name.__class__)
def test():
pass
print(test.__class__) # function
class demo:
pass
print(demo.__class__) # type
print(age.__class__.__class__) # type
print(name.__class__.__class__)
输出结果:
------------------------------
class Person(object):
def __init__(self, name=None, age=None):
self.name = name
self.age = age
P = Person("小明", "22")
P.sex = "male"
print(P.sex)
输出结果:
male
class Person(object):
def __init__(self, name=None, age=None):
self.name = name
self.age = age
p = Person("小丽", "23")
Person.sex = None
print(p.sex)
总结:
运行中给对象绑定属性-----》直接通过实例对象设置
运行中给类绑定属性-----》直接通过类对象设置
print("-" * 30)
class Person(object):
def __init__(self, name=None, age=None):
self.name = name
self.age = age
def eat(self):
print("吃饭....")
def run(self, speed):
print("%s在移动,速度%s" % (self.name, speed))
p = Person("老王", 23)
p.eat()
# p.run()
person = type("person", (Person,), {"run": run})
P = person("小王", "24")
P.run("220")
输出结果:
------------------------------
吃饭....
小王在移动,速度220
print("*" * 30)
import types
class Person(object):
def __init__(self, name=None, age=None):
self.name = name
self.age = age
def eat(self):
print("吃饭....")
def run(self, speed):
print("%s在移动,速度%s" % (self.name, speed))
P = Person("小王","24")
# P.run("220")
P.run = types.MethodType(run,P)#第一个参数L:需要添加的方法,参数二:添加到该类的实例对象
P.run("100")
运行结果:
******************************
小王在移动,速度100
#### 动态添加一个静态方法
#
# 定义一个类方法
@classmethod
def testClass(cls):
cls.num = 150
# 定义一个静态方法
@staticmethod
def testStatic():
print("----static method-----")
P = Person("老王",22)
Person.testClass = testClass # 把静态方法加入到类中
Person.testClass() # 调用类的静态方法,执行方法中的方法体
print(Person.num) # 输出调用内容
print("$" * 30)
# 添加静态方法
Person.testStatic = testStatic
Person.testStatic()
输出结果:
******************************
150
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
----static method-----
## 13.10_Python语言基础(运行过程中删除属性和方法)(熟练)
* 删除的方法:
* del 对象.属性名
* delattr(对象,"属性名")
## 13.11_Python语言基础(__slots__)(熟练)
* 动态语言:可以在运行的过程中,修改带啊没
* 静态语言:便编译时已经确定的代码,运行的时候不能修改
* 如果我们想要限制实例属性?
* 允许对Person实例中添加name和age属性,
* python允许再买定义class的时候,定义一个特殊的变量----__slots__
* __slots__能限制class能够添加的属性
#
class Person(object):
__slots__ = ("name", "age")
P = Person()
P.name = "老王"
P.age = 80
# P.sex = "male"
# 试一试这个限制是否对子类起作用
class Demo(Person):
pass
d = Demo()
d.sex = "male"
>**注意:**
使用__slots__定义的属性仅对当前类实例起作用,对继承的子类不起作用
***
## 13.12_Python语言基础(@property)(掌握)
### 私有的属性添加给getter和setter
#
class Money(object):
def __init__(self):
self.__money = 0
def getMoney(self):
return self.__money
def setMoney(self, value):
if isinstance(value, int):
self.__money = value
else:
print("error:不是整型")
# 先后调用两个方法,调用set方法的值,通过set设置
money = property(getMoney, setMoney)
a = Money()
print(a.money)
a.money = 100
print(a.money)
print(a.getMoney())
#### 使用property实现getter 和 setter方法的功能
#
如何实现set/get------》修饰器-----》@property
@property--->属性函数,可以对属性赋值时候做必要的检查,并保证代码的原有功能
作用:
1.将方法转化为只读
2.重新实现一个属性的设置和读取方法,可做边界判定
class Money:
def __init__(self):
self.__money = 0
@property
def money(self):
return self.__money
@money.setter
def money(self, value):
if isinstance(value, int):
self.__money = value
else:
print("error....")
a = Money()
print(a.money)
a.money = 189
print(a.money)
#### 案例2:
#
#使用set和get方法
class Person(object):
def __init__(self,name,age):
#属性直接对外暴露
# self.age = 12
#限制属性
self.__name = name
self.__age = age
def getAge(self):
return self.__age
def setAge(self,age):
if age < 0:
age = 0
self.__age = age
# 使用修饰器实现set和get功能
print("*" * 30)
class Person:
def __init__(self):
self.__name = "oo"
self.__age = 34
@property
def age(self):
return self.__age
@age.setter
def age(self, age):
if age > 0 and age < 100:
self.__age = age
p = Person()
print(p.age)
## 13.13_Python语言基础(运算符的重载)(熟练)
* 同样的运算符执行不同数据之间的运算时,采用不同的计算方式
#### 运算符的重载案例:
#
print(1+2)
print("1"+"2")
#案例2:
#
class Person(object):
def __init__(self,num):
self.num = num
#运算符重载
def __add__(self, other):
return Person(self.num+other.num)
def __str__(self):
return "num="+str(self.num)
per1 = Person(1)
per2 = Person(2)
print(per1+per2)#3 ====print(per1.__add__(per2))
print(per1.__add__(per2))
print(per1)
print(per2)
我们日常中操作文件的过程:
打开一个文件 ,或者新建一个文件
读写数据
关闭文件
在python中,使用open()函数可以打开一个已经存在的文件,或者创建一个新的文件
格式:
open(文件名,访问模式)
f = open("test.txt","w")
访问模式 说明
w 打开一个文件只用于写入,如果该文件已经存在则将其覆盖,如果不存在,创建新文件
r 以只读的方式打开一个文件,文件的指针将会在文件的开头位置,默认模式,如果文件不存在会报错
a 打开一个文件用于追加,如果该文件已经存在,文件的指针会放在文件的结尾,即新的内容将会写入已有内容之后,如果文件不存在,如果文件不存在,创建以一个新文件进行写入
rb 以二进制的方式打开一个文件用于只读,文件的指针将会在文件的开头位置,默认模式,如果文件不存在会报错
wb 以二进制的格式打开一个文件只用于写入,如果该文件已经存在则将其覆盖,如果不存在,创建新文件
ab 以二进制方式打开一个文件用于追加,如果该文件已经存在,文件的指针会放在文件的结尾,即新的内容将会写入已有内容之后,如果文件不存在,如果文件不存在,创建以一个新文件进行写入
r+ 打开一个文件用于读写,文件的指针放在文件的开头位置
w+ 打开一个文件用于读写,如果该文件已经存在将其覆盖,如果文件不存在,创建一个新文件
a+ 打开一个文件用于读写,文件的指针放在文件的末尾位置,,即新的内容将会写入已有内容之后,如果文件不存在,如果文件不存在,创建以一个新文件进行写入
rb+ 以二进制的方式打开一个文件用于读写,文件的指针放在文件的开头位置
wb+ 以二进制的方式打开一个文件用于读写,如果该文件已经存在将其覆盖,如果文件不存在,创建一个新文件
ab+ 以二进制的方式打开一个文件用于读写,文件的指针放在文件的末尾位置,,即新的内容将会写入已有内容之后,如果文件不存在,如果文件不存在,创建以一个新文件进行写入
使用函数:
close()
f = open("test.txt","w")
f.close()
"""
注意:
close()作用---》节省内存
使用write()函数可以完成对文件写入内容
格式:
f.write(str)
f = open("test.txt","w")
f.write("hello world !")
f.close()
注意:
如果文件不存在则创建,如果存在,则先清空,在写入数据
1.读取数据使用read()函数,可以从文件中读取数据,
格式:
read(num)
num : 表示要从文件中读取的数据的长度(单位字节),
如果num没有传入,那么表示读取文件的所有数据
"""
# f = open("test.txt")
# content = f.read()
# print(content)
# content1 = f.read(5)
# print(content1)
# f.close()
注意:
如果使用了多次,那么后面读取的数据是从
上一次读取完数据后的位置开始
使用readlines可以按照行的方式把整个的文件中的内容进行一次性读取,
返回一个列表,其中每一行的数据作为一个元素
- f = open("test.txt", "r+")
f.write("hello python \n hello python \n hello python \nhello python ")
content = f.readlines()
print(type(content))
print(content)
获取列表中所有的内容
i = 1
for temp in content:
print("%d:%s" % (i, temp))
i += 1
f.close()
运行输出结果:
['hello python \n', ' hello python \n', ' hello python \n', 'hello python ']
1:hello python
2: hello python
3: hello python
4:hello python
读取指定文件的所有内容:
def Open_File(filename):
OldFile=open(filename,"r",encoding="GBK")
readfile=OldFile.readline()
while readfile!="":
print(readfile,end="")
readfile = OldFile.readline()
OldFile.close()
# C:\Users\Administrator\Desktop\123.txt
filename=input(":")
Open_File(filename)
# 导入CSV模块 pdf 图片
import csv
def readCsv(path):
infoList = []
with open(path,"r") as f:
allFileInfo = csv.reader(f)
# print(type(allFileInfo))
for row in allFileInfo:
infoList.append(row)
return infoList
path = r"E:\Files\上海校区Python基础班\day14\资料\csv\000002.csv"
info = readCsv(path)
print(info)
import csv
def writeCsv(path,data):
with open(path,"w") as f:
writer = csv.writer(f)
for rowDate in data:
writer.writerow(rowDate)
path = r"E:\Files\上海校区Python基础班\day14\资料\000002.csv"
writeCsv(path,[["1","2","3"],["4","5","6"],["7","8","9"]])
任务描述:
输入文件名字,然后程序自动完成对该文件的备份操作:
分析:
input()–>string
open()
判断用户输入的文件是否存在
存在
1.打开文件
2.读取数据
3.关闭文件
不存在----》错误提示
完成备份:
1.拿到刚才读取到的数据
2.创建一个新文件,将刚才读取到的数据写到这个新文件中
3.关闭文件
oldFileName = input("请输入需要备份的文件:")
#打开需要备份的文件
oldFile = open(oldFileName,"r")
#读取需要备份文件的内容
#判断是否打开
if oldFile:
#提取文件的后缀名
fileFlagNum = oldFileName.rfind(".")
if fileFlagNum > 0:
fileFlag = oldFileName[fileFlagNum]
#组织新文件的名字
newFilename = oldFileName[:fileFlagNum]+"[复件]"+fileFlag
#创建一个新的文件
newFile = open(newFilename,"w")
#将旧文件中的数据,一行一行的方式进行复制到新文件中
for lineContent in oldFile.readlines():
newFile.write(lineContent)
#关闭文件
oldFile.close()
newFile.close()
"""
获取当前读写文件的位置
在读取文件的过程中,如果想知道当前的位置,
可以使用函数tell()来获取,是光标开始的位置
"""
# 打开一个文件
f = open("test.txt", "r")
str = f.read(3)
print(str)
# 查找当前光标的位置
position = f.tell()
print(position)
str = f.read(3)
position = f.tell()
print(position)
f.close()
如果在读写文件的过程中,需要从另外一个位置进行操作,可以使用seek()函数
格式:
seek(offset,from)
offset:偏移量
from:方向
0:表示文件的开头
1:表示当前位置
2:表示文件的末尾
案例L:
把位置设置为:从文件的开头,偏移5个字节
"""
#打开一个文件
f = open("test.txt","rb+")
str = f.read(30)
print(str)
#查找光标当前的位置
# position = f.tell()
# print(position)
#重新设置位置
f.seek(-3,2)
position = f.tell()
print(position)
f.close()
注意:
如果打开文件的模式"r",而不是"rb",则会报错
在文本文件中,没有使用b模式选项打开文件,只允许从文件的开头计算相对位置
概述:
需要对文件进行重命名操作,删除,python中有一个模块os模块----》文件的操作
os模块中有 一个函数rename()可以完成对文件名的重新命名
格式和案例:
rename(需要修改的文件名,,新的文件名)
- - import os
- os.rename("test.txt","毕业论文.txt")
概述:
os模块中remove()可以完成对文件的删除操作
格式:
remove(待删除的文件名)
案例:
os.remove("毕业论文.txt")
概述:
使用os模块中mkdir()函数
格式:
mkdir(str)
案例:
import os
os.mkdir("张三")
概述:
使用os模块中listdir()函数
格式:
listdir()
案例:
import os
print(os.listdir("./"))
#结果为当前目录的文件
概述:
使用os模块中的rmdir()函数
格式:
rmdir(str)
str--->表示需要删除的文件夹名称
案例:
import os
os.rmdir("张三")
"""
StringIO
"""
from io import StringIO
f = StringIO()
f1 = f.write("hello")#返回的是写入数据的字节数(每次写入的数据)
print(type(f1))
print(f1)#5
f2 = f.write(" ")
print(f2)#1
f3 = f.write("world!")
print(f3)#6
print(f)
print(f.getvalue())
"""
读取StringIO文件,可以用一个str初始化StringIO,
"""
f = StringIO("hello\nhi\ngoodbye!")
while True:
s = f.readline()
if s == "":
break
print(s.strip())
StringIO操作---》str
如果操作二进制数据,需要使用BytesIO
BytesIO实现在内存中读取byte数据
print("------test-----1")
open("123.txt","r")
print("-----test------2")
当python检测到一个错误时,解释器就无法继续执行,反而出现错误提示—>异常
当出现异常的时候如何处理?
try:
print("------test-----1")
open(“123.txt”,“r”)
except FileNotFoundError:
print(“找不到该文件”)
print("-----test------2")
print("-----test 3")
程序看不到任何错误,因为用来except,
捕获到FileNotFoundError异常,并添加了处理方法
总结:
把可能出现问题的代码,放在try里面,
把异常处理的代码放在except中
try:
print("------test-----1")
open("123.txt","r")
except (IOError,NameError):
print("找不到该文件")
print("-----test------2")
print("-----test 3")
"""
报错,异常处理的类型不正确
"""
try:
print("----test---1----")
print(AA.aa())
open("123.txt","r")
print("-----test-----2")
except (NameError,FileNotFoundError):
print("----test 3")
try:
open("123.txt","r")
except FileNotFoundError as ss:
# print("文件不存在....")
print(ss)
"""
关键字as as后面跟的是错误的描述信息errorMsg
那么它的基本格式:
except (错误类型) as 错误的描述:
return 错误描述
# exception
try:
# open("133.txt","r")
# print(AA.aa())
print(abcd)
open("134.txt", "r")
print(AB.aa())
print(abcdaaa)
except Exception as reslut:
print(reslut)
概述:
except NameError as errormsg:
print(errormsg)
else:
print("没有捕获到异常,真高兴!")
import os
import time
# os.remove("123.txt")
try:
f = open("test.txt")
try:
while True:
content = f.readline()
if len(content) == 0:
break
try:
time.sleep(2)
finally:
print("haha")
print(content)
finally:
f.close()
print("文件关闭")
except:
print("没有该文件")
finally:
print("最后的finally")
class A(object):
pass
def test1():
print("----test1----1")
print(A.hello())
print("------test1-----2")
def test2():
print("----test2----1")
test1()
print("------test2-----2")
def test3():
try:
print("----test3----1")
test1()
print("------test3-----2")
except Exception as reslut:
print(reslut)
finally:
print("nihao")
test3()
如何定义一个自定义的异常
raise语句的基本的格式
raise 自定义的异常类的对象
自定义的异常类
class ShortInputException(Exception):
def __init__(self,length,atleast):
self.length = length
self.atleast = atleast
aa = ShortInputException()
def main():
try:
str = input("请输入....")
if len(str) < 3:
raise ShortInputException(len(str),3)
except ShortInputException as reslut:
print("ShortInputException:输入的长度是%d,长度应该大于%d"%(reslut.length,reslut.atleast))
else:
print("没有异常的发生")
main()
class Test(object):
def __init__(self,switch):
self.switch = switch
def calc(self,a,b):
try:
return a/b
except Exception as reslut:
if self.switch:
print("捕获开启,已经捕获到异常,信息如下:")
print(reslut)
else:
#重新抛出异常,此时不会被这个异常给捕获到,从而去触发默认的异常处理
raise
a = Test(True)
# a.calc(11,0)
a.switch = False
a.calc(11,0)
# 打开英汉字典文件
file = open("dict.txt", "r", encoding="utf-8")
# 读取字符串
lines = file.readlines()
# 创建字典
dictionary = {}
# 字典添加内内容
for i in lines:
line_list = i.split("\t")
dictionary[line_list[0]] = line_list[1]
# 单词查询功能
while True:
print("请输入要查询的单词,输入0退出:")
eng = input()
if eng == "0":
break
if eng in dictionary.keys():
print(eng + ":\t" + dictionary[eng])
else:
print("您查询的词尚未收录,敬请期待")
使用方式:
import tkinter
创建主窗口
window = tkinter.Tk()
设置标题
window.title("英汉词典")
设置窗口的大小和位置400×400:宽高 200+20 初始化时候窗口的位置
window.geometry("400x400+200+20") # 符号为(x)小写矮科斯
显示内容
window.mainloop()
import tkinter
#创建主窗口
window = tkinter.Tk()
#设置标题
window.title("英汉词典")
#设置窗口的大小和位置400×400:大小宽高 200 20 初始化时候窗口所在的位置
window.geometry("400x400+200+20")
"""
window:父窗体
text:显示的文本内容
bg:背景
fg:字体颜色
wrapLength :指定text文本中多宽进行换行
justify:设置换行后的对齐方式
anchor: 位置 n 北 e 东 s南 w 西 center 居中
"""
label = tkinter.Label(window,text="1806",
bg="blue",fg="red",
font=("黑体",20),width="10",
height="4",wraplength= 100,
justify="left",anchor = "center")
# 管理控件
label.pack()#pack是一个布局管理器,一个弹性的容器
# 循环消息
window.mainloop()
import tkinter
# 创建窗口
from tkinter import Frame
window = tkinter.Tk()
# 设置窗口
window.title("英汉词典")
window.geometry("500x500")
# 控制台输出信息的方法
def show_info():
print("666")
btn_show = tkinter.Button(window, text="查询", command=show_info)
btn_show.pack(side="left")
# 退出按钮
btn_exit = tkinter.Button(window, text="退出", command=window.quit)
btn_exit.pack(side="right")
# 按钮布局
btn_frame = Frame(window, height=30)
btn_frame.pack()
#
# # 显示按钮
# btn_show = tkinter.Button(btn_frame, text="查询", command=show_info)
# btn_show.pack(side="left")
#
# # 退出按钮
# btn_exit = tkinter.Button(btn_frame, text="退出", command=window.quit)
# btn_exit.pack(side="right")
# 消息循环
window.mainloop()
Text:
import tkinter
from tkinter import *
创建窗口
window = tkinter.Tk()
配置窗口
window.title("英汉词典")
window.geometry("500x300")
window.resizable(width=True, height=False)
文本显示框
text = Text(window, width=68, height=20)
text.pack(side="bottom")
文本框插入内容
word = "hello hello hello hello hello hello hello hello hello"
text.insert(tkinter.INSERT, word)
消息循环
window.mainloop()
import tkinter
# 创建窗口
window = tkinter.Tk()
# 设置窗口
window.title("英汉词典")
window.geometry("500x500")
# 输入框
entry = tkinter.Entry(window)
entry.pack()
# 控制台输出内容
def show_info():
print(entry.get())
# 按钮
button = tkinter.Button(window, text="查询", command=show_info)
button.pack()
# 消息循环
window.mainloop()
import tkinter
from tkinter import *
# 显示信息
def show_info():
text.insert("1.0", entry.get() + "\n")
# 创建窗口
window = tkinter.Tk()
# 配置窗口
window.title("英汉词典")
window.geometry("500x300")
window.resizable(width=True, height=False)
# 输入框布局
input_frame = Frame(window, width=30, height=30)
input_frame.pack(side="top")
# 输入框
entry = Entry(input_frame, width=30)
entry.pack(side="left")
# 查询按钮
btn_search = Button(input_frame, text="查询", command=show_info)
btn_search.pack(side="left")
# 退出按钮
btn_search = Button(input_frame, text="退出", command=window.quit)
btn_search.pack(side="right")
# 文本
text = Text(window, width=68, height=20)
text.pack(side="bottom")
# 循环消息
window.mainloop()
import tkinter
from tkinter import *
# 显示信息
def show_info():
text.insert("1.0", entry.get() + "\n")
# 创建窗口
window = tkinter.Tk()
# 配置窗口
window.title("英汉词典")
window.geometry("500x300")
window.resizable(width=True, height=False)
# 输入框布局
input_frame = Frame(window, width=30, height=30)
input_frame.pack(side="top")
# 输入框
entry = Entry(input_frame, width=30)
entry.pack(side="left")
# 查询按钮
btn_search = Button(input_frame, text="查询", command=show_info)
btn_search.pack(side="left")
# 退出按钮
btn_search = Button(input_frame, text="退出", command=window.quit)
btn_search.pack(side="right")
# 滚动条
scroll = tkinter.Scrollbar()
scroll.pack(side="right", fill=tkinter.Y)
# 文本
text = Text(window, width=68, height=20)
text.pack(side="bottom")
# 关联滚动条和文字
text.config(yscrollcommand=scroll.set)
scroll.config(command=text.yview)
# 循环消息
window.mainloop()
单选按钮:
import tkinter
# 创建窗口
from tkinter import Checkbutton, IntVar, Radiobutton
window = tkinter.Tk()
# 设置窗口参数
window.title("英汉词典")
window.geometry("500x500")
# 一组按钮绑定一个变量
check_box = tkinter.BooleanVar()
# 接收显示结果
def send_result():
print(check_box.get())
# 创建单选按钮
radio_man = Radiobutton(window, text="man", value=True, variable=check_box, command=send_result)
radio_woman = Radiobutton(window, text="woman", value=False, variable=check_box, command=send_result)
# 管理控件
radio_man.pack()
radio_woman.pack()
# 循环消息
window.mainloop()
多选按钮示例:
import tkinter
from tkinter import Checkbutton, StringVar, BooleanVar
# 创建窗口
window = tkinter.Tk()
# 设置窗口参数
window.title("英汉词典")
window.geometry("500x500")
# 存放选中信息
hobby_list = set()
# 获取选中信息
def update_info():
if check_01.get():
hobby_list.add("篮球")
else:
if "篮球" in hobby_list:
hobby_list.remove("篮球")
if check_02.get():
hobby_list.add("足球")
else:
if "足球" in hobby_list:
hobby_list.remove("足球")
if check_03.get():
hobby_list.add("排球")
else:
if "排球" in hobby_list:
hobby_list.remove("排球")
print(hobby_list)
# 给每一个选项创建一个变量
check_01 = BooleanVar()
check_02 = BooleanVar()
check_03 = BooleanVar()
# 复选框
check_box_01 = Checkbutton(window, text="篮球", variable=check_01, command=update_info)
check_box_02 = Checkbutton(window, text="足球", variable=check_02, command=update_info)
check_box_03 = Checkbutton(window, text="排球", variable=check_03, command=update_info)
# 管理控件
check_box_01.pack()
check_box_02.pack()
check_box_03.pack()
# 循环消息
window.mainloop()
import tkinter
from tkinter import Label
# 创建窗口
window = tkinter.Tk()
# 设置窗口参数
window = tkinter.Tk()
window.title("英汉词典")
window.geometry("500x500")
# 创建控件
label_01 = Label(window, text="label_01", bg="blue")
label_02 = Label(window, text="label_02", bg="green")
label_03 = Label(window, text="label_03", bg="red")
# 管理控件
label_01.place(x=10, y=10)
label_02.place(x=50, y=50)
label_03.place(x=100, y=100)
# 循环消息
window.mainloop()
import tkinter
from tkinter import Label
# 创建窗口
window = tkinter.Tk()
# 设置窗口参数
window = tkinter.Tk()
window.title("英汉词典")
window.geometry("500x500")
# 创建控件
label_01 = Label(window, text="label_01", bg="blue")
label_02 = Label(window, text="label_02", bg="green")
label_03 = Label(window, text="label_03", bg="red")
# 管理控件
label_01.pack(fill=tkinter.Y, side=tkinter.LEFT)
label_02.pack(fill=tkinter.X, side=tkinter.TOP)
label_03.pack(fill=tkinter.X, side=tkinter.LEFT)
# 循环消息
window.mainloop()
import tkinter
from tkinter import Label
# 创建窗口
window = tkinter.Tk()
# 设置窗口参数
window = tkinter.Tk()
window.title("英汉词典")
window.geometry("500x500")
# 创建控件
label_01 = Label(window, text="label_01", bg="blue")
label_02 = Label(window, text="label_02", bg="green")
label_03 = Label(window, text="label_03", bg="red")
label_04 = Label(window, text="label_01", bg="yellow")
label_05 = Label(window, text="label_02", bg="orange")
label_06 = Label(window, text="label_03", bg="pink")
# 管理控件
label_01.grid(row=1, column=1)
label_02.grid(row=2, column=2)
label_03.grid(row=3, column=3)
label_04.grid(row=1, column=4)
label_05.grid(row=2, column=5)
label_06.grid(row=3, column=6)
# 循环消息
window.mainloop()
import tkinter
from tkinter import Label, GROOVE, SUNKEN, RAISED, FLAT, RIDGE
# 创建窗口
window = tkinter.Tk()
# 设置窗口参数
window.title("英汉词典")
window.geometry("500x500")
"""
relief:3D效果
FLAT ---平的
RAISED ---凸起的
RIDGE ---脊状边缘
SUNKEN ---凹陷
GROOVE ---沟状
"""
# 创建控件
label_01 = Label(window, text="label_01", bg="blue", relief=GROOVE)
label_02 = Label(window, text="label_02", bg="green", relief=SUNKEN)
label_03 = Label(window, text="label_03", bg="red", relief=RAISED)
label_04 = Label(window, text="label_04", bg="yellow", relief=FLAT)
label_05 = Label(window, text="label_05", bg="orange", relief=RIDGE)
# 管理控件
label_01.grid(row=1, column=1)
label_02.grid(row=2, column=2)
label_03.grid(row=3, column=3)
label_04.grid(row=4, column=4)
label_05.grid(row=5, column=5)
# 循环消息
window.mainloop()
结合以上知识,编写代码实现带界面的字典
import tkinter
window=tkinter.Tk()
window.title("英汉字典")
window.geometry("500x500")
def printf_info():
DictionaryPath = r"C:\Users\Administrator\PycharmProjects\PythonText\ModularText\Files\dict.txt"
DictList = {}
DictionaryFile = open(DictionaryPath, "r", encoding="utf-8-sig")
ReadDictionaryFile = DictionaryFile.readlines()
for R_line in ReadDictionaryFile:
Dictionary = R_line.split("\t")
DictList[Dictionary[0]] = Dictionary[1]
Word = entry.get()
text.delete(0.0,tkinter.END)
if Word in DictList:
info=Word+ ":"+ DictList[Word]
text.insert(tkinter.INSERT,info)
elif Word=="":
info = "输入为空,重新输入。"
text.insert(tkinter.INSERT, info)
else:
info="无该单词!"
text.insert(tkinter.INSERT,info)
DictionaryFile.close()
frame=tkinter.Frame(window,width=30)
frame.pack()
label=tkinter.Label(frame,text="输入单词:",font=("黑体",15))
label.pack(side="left")
entry=tkinter.Entry(frame,font=("黑体",15))
entry.pack(side="left")
# 点击打印按钮,执行printf_info()函数,
button=tkinter.Button(frame,text="翻译",font=("黑体",15),command=printf_info)
button.pack(side="right")
# 显示结果的text,将对这输入显示翻译结果呢
text=tkinter.Text(window,font=("黑体",15))
text.pack()
window.mainloop()
字符 功能
. 匹配任意1个字符(除\n)
[] 匹配[]中列举的字符
\d 匹配数字(0~9)
\D 匹配非数字,即不是数字
\s 匹配空白 空格 tab
\S 匹配非空白
\w 匹配单词字符,a~z A~Z 0~9 _
\W 匹配非单词字符
字符 功能
* 表示匹配前一个字符出现0次或者无限次,即可有可无
+ 表示匹配前一个字符出现1次或者无限次,即至少一次
? 表示匹配前一个字符出现1次或则0次, 即,要么一次,要么没有
{m} 表示匹配前一个字符出现m次
{m,} 表示前一个字符至少出现m次
{m,n} 表示匹配字符出现从m到n次
字符 功能
^ 匹配字符串的开头
$ 匹配字符串的结尾
\b 表示匹配一个单词的边界
字符 功能
| 匹配左右任意一个表达式
(ab) 将括号中字符作为分组
\num 引用分组num匹配到字符串
re.match
尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回""()None。
re.search
匹配成功re.search方法返回一个匹配的对象,否则返回None。(不限制第一个字符)
re.match与re.search的区别:
re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None,而re.search匹配整个字符串,直到找到一个匹配。
import re
pattern = re.compile(r'\d+')
m = pattern.match('one12twothree34four')
print(m)
re.compile
用于编译正则表达式,生成一个正则表达式( Pattern )对象,供 match() 和 search() 这两个函数使用。
re.findall (返回空列表)
在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表。
re.finditer(返回迭代器)
和 findall 类似,在字符串中找到正则表达式所匹配的所有子串,并把它们作为一个迭代器返回。
re.split(可扩展)
split 方法按照能够匹配的子串将字符串分割后返回列表,
语法:
re.sub(pattern, repl, string, count=0, flags=0)
参数:
pattern : 正则中的模式字符串。
repl : 替换的字符串,也可为一个函数。
string : 要被查找替换的原始字符串。
count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配
re.RegexObject
re.compile() 返回 RegexObject 对象。
re.MatchObject
group() 返回被 RE 匹配的字符串。
start() 返回匹配开始的位置
end() 返回匹配结束的位置
span() 返回一个元组包含匹配 (开始,结束) 的位置
字符串中必须含有每个()中的一个参数
import re
word="123_qwe_QQWE"
#********一下的为一行********
result=re.match(
"(?=.*[a-zA-Z])(?=.*[0-9])"
"(?=.*[_@\.!#%&])"
"[a-zA-Z_0-9@\.!@#%&]{6,20}$"
"",word).group()
#********以上的为一行********
print(result)
计算机为了联网,就必须规定通信协议,,都是由各厂商自己规定早期的计算机网络一套协议
IBM、Apple和Microsoft都有各自的网络协议,互不兼容,这就好比一群人有的说英语,
有的说中文,有的说德语,说同一种语言的人可以交流,不同的语言之间就不行了。
为了把全世界的所有不同类型的计算机都连接起来,就必须规定一套全球通用的协议,
为了实现互联网这个目标,互联网协议簇(Internet Protocol Suite)就是通用协议标准。
Internet是由inter和net两个单词组合起来的,原意就是连接“网络”的网络,
有了Internet,任何私有网络,只要支持这个协议,就可以联入互联网。
因为互联网协议包含了上百种协议标准,但是最重要的两个协议是TCP和IP协议,
所以,大家把互联网的协议简称TCP/IP协议。
通信的时候,双方必须知道对方的标识,好比发邮件必须知道对方的邮件地址。
互联网上每个计算机的唯一标识就是IP地址,类似123.123.123.123。
如果一台计算机同时接入到两个或更多的网络,比如路由器,它就会有两个或多个IP地址,
所以,IP地址对应的实际上是计算机的网络接口,通常是网卡。
IP协议负责把数据从一台计算机通过网络发送到另一台计算机。
数据被分割成一小块一小块,然后通过IP包发送出去。
由于互联网链路复杂,两台计算机之间经常有多条线路,
因此,路由器就负责决定如何把一个IP包转发出去。
IP包的特点是按块发送,途径多个路由,但不保证能到达,也不保证顺序到达。
TCP协议则是建立在IP协议之上的。TCP协议负责在两台计算机之间建立可靠连接,保证数据包按顺序到达。
TCP协议会通过握手建立连接,然后,对每个IP包编号,确保对方按顺序收到,如果包丢掉了,就自动重发。
许多常用的更高级的协议都是建立在TCP协议基础上的,比如用于浏览器的HTTP协议、发送邮件的SMTP协议等。
一个IP包除了包含要传输的数据外,还包含源IP地址和目标IP地址,源端口和目标端口。
端口有什么作用?在两台计算机通信时,只发IP地址是不够的,因为同一台计算机上跑着多个网络程序。
一个IP包来了之后,到底是交给浏览器还是QQ,就需要端口号来区分。
每个网络程序都向操作系统申请唯一的端口号,
这样,两个进程在两台计算机之间建立网络连接就需要各自的IP地址和各自的端口号。
一个进程也可能同时与多个计算机建立链接,因此它会申请很多端口。
Socket又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求,
使主机间或者一台计算机上的进程间可以通讯。
Socket是网络编程的一个抽象概念。通常我们用一个Socket表示“打开了一个网络链接”,而打开一个Socket需要知道目标计算机的IP地址和端口号,再指定协议类型即可。
Python 中,我们用 socket()函数来创建套接字,语法格式如下:
socket.socket([family[, type[, proto]]])
family: 套接字家族可以使AF_UNIX或者AF_INET
type: 套接字类型可以根据是面向连接的还是非连接分为SOCK_STREAM或SOCK_DGRAM
protocol: 一般不填默认为0.
socket编程有UDP和TCP两种传输协议
UDP则是面向无连接的协议。
使用UDP协议时,不需要建立连接,只需要知道对方的IP地址和端口号,就可以直接发数据包。
但是,能不能到达就不知道了。
虽然用UDP传输数据不可靠,但它的优点是速度快(和TCP比),对于不要求可靠到达的数据,就可以使用UDP协议。
我们来看看如何通过UDP协议传输数据。使用UDP的通信双方分为客户端和服务器。
服务器首先需要绑定端口:
UDP编程步骤要简单许多,分别如下:
"""
1、创建一个socket,用函数socket();
2、设置socket属性,用函数setsockopt();* 可选
3、绑定IP地址、端口等信息到socket上,用函数bind();
4、循环接收数据,用函数recvfrom();
5、关闭网络连接;
"""
import socket
"""
1、创建一个socket,用函数socket();
2、设置socket属性,用函数setsockopt();* 可选
3、绑定IP地址、端口等信息到socket上,用函数bind();* 可选
4、设置对方的IP地址和端口等属性;
5、发送数据,用函数sendto();
6、关闭网络连接;
"""
import socket
* 创建 socket 套接字:
* bind 绑定
* listen 监听
* accept 接受请求连接
* 接收数据
* 断开连接
创建 socket 套接字:
server_tcp = socket.socket()
bind 绑定
ip_port = (“172.16.5.236”, 10086)
server_tcp.bind(ip_port)
* 创建socket对象
* 确定IP
* 建立客户端连接
* 发送消息
* 断开连接
import socket
# 创建socket对象
client_tcp = socket.socket()
ip_port = ("172.16.5.236", 10086)
# 建立客户端连接
client_tcp.connect(ip_port)
while True:
# 发送消息
msg = input("请输入消息:")
if len(msg) == 0:
continue
elif msg == "exit":
break
client_tcp.sendall(bytes(msg, encoding="utf-8"))
# 接收消息
data = client_tcp.recv(1024)
print(str(data, encoding="utf-8"))
# 断开连接
client_tcp.close()
import socket
# 创建socket对象
server_tcp = socket.socket()
# 主机地址和端口号
ip_port = ("172.16.5.236", 10086)
# 绑定主机地址和端口号
server_tcp.bind(ip_port)
# 监听
server_tcp.listen(5)
# 建立客户端连接
conn, addr = server_tcp.accept()
while True:
# 接收消息
data = conn.recv(1024)
if not data:
break
else:
print(str(data, encoding="utf-8"))
# 回复消息
msg = input("请回复:").strip()
if len(data) == 0:
continue
conn.sendall(bytes(msg, encoding="utf-8"))
# 断开连接
conn.close()
对系统资源的要求(TCP较多,UDP少)
UDP程序结构较简单
流模式与数据报模式
TCP保证数据正确性,UDP可能丢包
TCP保证数据顺序,UDP不保证
部分满足以下几点要求时,应该采用UDP 面向数据报方式 网络数据大多为短消息
拥有大量Client
对数据安全性无特殊要求
网络负担非常重,但对响应速度要求高
具体编程时的区别 socket()的参数不同
UDP Server不需要调用listen和accept
UDP收发数据用sendto/recvfrom函数
TCP:地址信息在connect/accept时确定
UDP:在sendto/recvfrom函数中每次均 需指定地址信息
UDP:shutdown函数无效
UDP和TCP编程步骤也有些不同,如下:
TCP编程的服务器端一般步骤是:
1、创建一个socket,用函数socket();
2、设置socket属性,用函数setsockopt(); * 可选
3、绑定IP地址、端口等信息到socket上,用函数bind();
4、开启监听,用函数listen();
5、接收客户端上来的连接,用函数accept();
6、收发数据,用函数send()和recv(),或者read()和write();
7、关闭网络连接;
8、关闭监听;
TCP编程的客户端一般步骤是:
1、创建一个socket,用函数socket();
2、设置socket属性,用函数setsockopt();* 可选
3、绑定IP地址、端口等信息到socket上,用函数bind();* 可选
4、设置要连接的对方的IP地址和端口等属性;
5、连接服务器,用函数connect();
6、收发数据,用函数send()和recv(),或者read()和write();
7、关闭网络连接;
UDP编程的服务器端一般步骤是:
1、创建一个socket,用函数socket();
2、设置socket属性,用函数setsockopt();* 可选
3、绑定IP地址、端口等信息到socket上,用函数bind();
4、循环接收数据,用函数recvfrom();
5、关闭网络连接;
UDP编程的客户端一般步骤是:
1、创建一个socket,用函数socket();
2、设置socket属性,用函数setsockopt();* 可选
3、绑定IP地址、端口等信息到socket上,用函数bind();* 可选
4、设置对方的IP地址和端口等属性;
5、发送数据,用函数sendto();
6、关闭网络连接;