python入门之变量和基本数据类型
什么是变量
# 变量是变化的量,用来记录事物的某种属性。
为什么用变量
# 使用变量是为了让计算机和人类一样具有记忆功能,记录事物变化的状态。
变量的使用
变量的基本使用
使用原则:先定义后使用
name = 'egon' # 定义-》存
print(name) # 引用-》取
# name = 'egon'
# 在计算机内部的实现:
在内存中开辟一个快空间,将值'egon'放在其中,并给'egon'绑定一个别名,即变量名name,之后通过name来访问值'egon'
内存管理(垃圾回收机制)
# 变量使用前需要先定义。定义变量就是在内存中开辟一块空间用于数据储存,如果需要使用很多数据就需要开辟很多内存空间。
# 我们知道内存空间是有限的,如果定义的变量使用后就不再使用,这个变量依然会一直占用内存空间,这就会带来内存浪费问题,严重时还会造成内存溢出的问题。
# 这就需要我们在变量使用后及时释放这个变量所占用的内存空间。但是这个释放内存空间的工作是复杂又有分险的,幸运的是python解释器帮我们做了这部分工作。
# 什么是垃圾,垃圾指的是没有绑定变量名的值,也就是无法在访问的值,即没有用的值
# 如何回收垃圾:通过引用计数的方式,每当这个值被引用,即被绑定到一个新的变量名上,引用计数加1
x = 10 # x绑定给值10,10的引用计数=1
y = x # y绑定给值10,10的引用计数=2
z = 10 # z绑定给值10,10的引用计数=3
# 通过赋值可以将变量名绑定到值,将引用计数增加
# 通过del 方法可以将变量名和值解绑,将引用计数减少
del z # z与它所绑定的值解绑,即值10的引用计数减为2
# 注意 del不是不是删除z的意思本质是接触变量名的绑定,内存回收的目的
变量的三大组成部分
# I:变量名:是指向等号右侧值的内存地址的,用来访问等号右侧的值
# II:赋值符号:将变量值的内存地址绑定给变量名
# III:变量值:代表记录的事物的状态
变量名命名规则
# 1 变量名只能是 字母、数字或下划线的任意组合
# 2 变量名的第一个字符不能是数字
# 3 关键字不能声明为变量名,常用关键字如下:
['and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'exec', 'finally', 'for', 'from','global', 'if', 'import', 'in', 'is', 'lambda', 'not', 'or', 'pass', 'print', 'raise', 'return', 'try', 'while', 'with', 'yield']
变量的命名风格
# 纯小写字母加下划线连接单词
user_name = 'jack'
# 驼峰体
userName = 'jack'
# 命名需要见名知意,不要过长,推荐变量名使用下划线连接的方式
变量值三个重要的特征
id:反映的是变量值的内存地址,内存地址不同id则不同
type:反映的是变量的数据类型,不同的值用来表示不同的状态
value:指的是值本身
# 查看id的方法 id(name)
# 查看type的方法 type(name)
# 查看值的方法:print(name)
is & == 的区别
# is 用来判断两个变量的id地址是否相同
# == 用来判断两个变量的值是否相同
# 值相同,id地址可能不同
# id相同,值一定相同
# 实例
>>> x = 300
>>> y = 300
>>> print(id(x), id(y))
(94253136L, 94253040L)
小整数池
# 我们知道定义一个变量,就是在内存中开辟一块空间用于数据存储。
# 这就是为啥相同值会有不同的内存空间,即不同的id的原因。不同的内存空间,id肯定不同。
# 但是我们会发现在python解释器中,有如下的现象
>>> m = 10
>>> n =10
>>> id(m), id(n)
(87384912L, 87384912L)
# 变量m和变量n的id居然是相同的,为什么?
# 这是因为python解释器中存在一个小整数池的概念。
# 所谓小整数池指的是,python解释器会在程序开始运行的时候就预先开辟一块内存空间,存放一部分整数。以后程序需要用到一些变量绑定到这些值时,直接绑定到这个内存地址上,不需要再逐个开辟空间(开辟空间访问硬件需要资源消耗),这是python的一种资源优化机制。
# 整数池的范围是 -5~256
# 实例
>>> m = -5
>>> n = -5
>>> m is n
True
>>> m = -6
>>> n = -6
>>> m is n
False
# 相同的原因,字符串也存在这种机制,‘字符串池’
>>> name1 = 'egon'
>>> name2 = 'egon'
>>> name1 is name2
True
>>> name1 = 'egon-'
>>> name2 = 'egon-'
>>> name1 is name2
False
常量
常量即不变的量,python中并没有具体规定,对于常量,大家约定俗成的使用大写表示常量。
PI = 3.14 # 圆周率
WIDTH = 1 # 长度
# python中很多地方都是推荐指定某种规范和风格,但是如果不遵循也没问题。
基本数据类型入门
不同的变量有不同的意义和使用,于是就有了不同的数据类型。常用的数据类型有:
数字类型
# 记录数字:
# 整型 int
# 浮点型 float
#整型用来记录整数,浮点型用来记录小数
age = 20
nums = 5
height = 1.8
wight = 66.6
字符串
# 记录文本
# 字符串 str
# 字符串用来记录文本数据
# 字符串变量的定义方式有三种:单引号、双引号、三引号
# 变量单行时,使用单引号和双引号,没有任何区别;变量多行时,使用三引号,格式化字符串变量。
name = 'jack'
sex = "male"
user_info =
"""
name:jack,
sex:male
"""
布尔
# 判断对错
# 布尔型 bool
# 布尔类型数据,只有两个 True/False, 即非零即真
switch = True
flag = False
列表
# 记录多个数据信息
lise # 列表
# 列表
# 列表可以将任意类型的变量组织在一起,用中括号括起来,每个元素用逗号隔开。
student_names = ["jack", "jane", "cindy", "tony"]
# 访问列表中的元素可以通过索引下标的方式,在python中索引从0开始,即第一个元素下标为0, 依次后推
print(student_name[2]) # 打印 "cindy"
print(student_name[-1]) # 打印 "tony",下标为符号,表示倒数第几个元素
字典
# 字典 dict
# 字典是按照键值对的方式存放数据,键和值之间用冒号连接,每组键值对用逗号隔开。
user_info = {
"name": "jack",
"age": 18,
"sex": "male"
}
# 需要注意的是每个键是唯一的,不能重复,且键一般都是字符串和数字
# 从字典里面提出值通过键来获取
print(user_info["name"]) # 打印 "jack"
可变 & 不可变
# 判断原则1
可变:值改变,id不变
不可变:值改变,id改变
# 判断原则2:哈希(hash)
可变:不可hash
不可变:可hash
# 总结
可变:列表、字典
不可变:整形、浮点型、字符串、布尔
练习题
练习 一:认真读题,需要自己从题目中分析出应该存储的状态,然后选择合适的类型加以存储
# 1、病毒程序需要定期将监控到的数据写入日志文件,请记录下日志文件路径C:\a\b\c\adhsvc.dll.system32,方便后期处理
# log_path = r'C:\a\b\c\adhsvc.dll.system32'
# 2、病毒程序在上传文件时,发送的报头数据里需要包含文件信息:文件名a.txt、大小360,请记录下文件信息
# file_info = {'file_name': 'a.txt', 'file_size': 360}
# 3、程序运行过程中有一段错误日志需要记录下来,错误日志为"上传文件失败"
# log_error = '上传文件失败'
# 4、假设我收到一条信息要记录,信息为中病毒客户端的信息"[2020-02-18-17:00:48] 癞蛤蟆病毒感染者-> 80.82.70.187:33649 正在上传数据"
# recv_msg = '[2020-02-18-17:00:48] 癞蛤蟆病毒感染者-> 80.82.70.187:33649 正在上传数据'
# 5、把服务端ip地址存放下来,ip地址为10.0.10.11
# ip = '10.0.10.11'
# 6、病毒程序需要每隔3秒才运行一次,请记录下这个时间间隔
# time_interval = 3
练习二:嵌套取值操作
# 1、students_info=[['egon',18,['play',]],['alex',18,['play','sleep']]]
# 请取出第一个学生的第一个爱好
# print(students_info[0][2][0])
#2、针对字典
# info={
# 'name':'egon',
# 'hobbies':['play','sleep'],
# 'company_info':{
# 'name':'Oldboy',
# 'type':'education',
# 'emp_num':40,
# }
# }
# 请取出取公司名
# print(info['company_info']['name'])
#3、针对下述类型
# students=[
# {'name':'alex','age':38,'hobbies':['play','sleep']},
# {'name':'egon','age':18,'hobbies':['read','sleep']},
# {'name':'wupeiqi','age':58,'hobbies':['music','read','sleep']},
# ]
# 取第二个学生的第二个爱好
# print(students[1]['hobbies'][1])
练习三:选做题:编写用户登录接口
- 需求1、输入账号密码完成验证,验证通过后输出"登录成功";
- 需求2、可以登录不同的用户;
- 需求3、同一账号输错三次锁定(附加功能,在程序一直运行的情况下,一旦锁定,则锁定5分钟后自动解锁);
- 扩展需求:在3的基础上,完成用户一旦锁定,无论程序是否关闭,都锁定5分钟。
需求1:将账号和密码存放在字典中,账号名到key,方便取值
# 需求1:
account_info = {
'egon':{'pwd':'123456'}
}
while 1:
username = input('username >>>:').strip()
password = input('password >>>:').strip()
if username in account_info:
if password == account_info[username]['pwd']:
print('登录成功')
break
else:
print('wrong username or password, please try again')
else:
print('no username please check again')
需求2:支持多个账号,即在账号字典中多添加一个新的账号信息键值对
# 需求2:
account_info = {
'egon': {'pwd':'123456'},
'alex': {'pwd':'123456'}
}
while 1:
username = input('username >>>:').strip()
password = input('password >>>:').strip()
if username in account_info:
if password == account_info[username]['pwd']:
print('登录成功')
break
else:
print('wrong username or password, please try again')
else:
print('no username please check again')
需求3:在账号信息中添加两个键值对,记录登录失败次数和账号锁定时的时间用于计算锁定的时间
# 需求3:
import time
account_info = {
'egon': {'pwd':'123456', 'login_fail_nums': 0, 'lock_time': None},
'alex': {'pwd':'123456', 'login_fail_nums': 0, 'lock_time': None}
}
while 1:
username = input('username >>>:').strip()
password = input('password >>>:').strip()
# 判断账号是否存在
if username in account_info:
# 判断账户是否锁定
if account_info[username]['login_fail_nums'] == 3:
# 等待的时间
waited_time = int(time.time() - account_info[username]['lock_time'])
# 等待时间超过5min则账号解锁
if waited_time > 5*60:
account_info[username]['login_fail_nums'] = 0
account_info[username]['lock_time'] = None
else:
print(f'account locked, please login after {5*60 - waited_time} s')
continue
# 登录检查
if password == account_info[username]['pwd']:
print('登录成功')
# 连续三次登录失败才锁定账号
# 只要登录成功则重置登录失败此时为0
account_info[username]['login_fail_nums'] = 0
break
else:
# 登录失败,记录失败次数
account_info[username]['login_fail_nums'] += 1
msg = 'wrong username or password, please try again'
if account_info[username]['login_fail_nums'] == 3:
# 记录锁定的那个时刻,时间戳
account_info[username]['lock_time'] = time.time()
msg = 'account locked for max_login_fail_nums exceeded, please login after 5 min'
print(msg)
else:
print(f'no account: {username}, please check again')
扩展需求:把数据及时保存在本地硬盘,程序关闭也不影响锁定时间的计算
# 扩展需求:
import time
import json
# 从硬盘取数据
def read_account_info(account_info_json):
with open(account_info_json, 'r', encoding='utf-8') as f:
return json.loads(f.read())
# 数据保存硬盘
def write_account_info(account_info_dict):
with open('account_info.json', 'w', encoding='utf-8') as f:
f.write(json.dumps(account_info_dict))
# account_info = {
# 'egon': {'pwd':'123456', 'login_fail_nums': 0, 'lock_time': None},
# 'alex': {'pwd':'123456', 'login_fail_nums': 0, 'lock_time': None}
# }
# 从硬盘去账号信息转为内存中的字典
account_info = read_account_info('account_info.json')
while 1:
username = input('username >>>:').strip()
password = input('password >>>:').strip()
# 判断账号是否存在
if username in account_info:
# 判断账户是否锁定
if account_info[username]['login_fail_nums'] == 3:
# 等待的时间
waited_time = int(time.time() - account_info[username]['lock_time'])
# 等待时间超过5min则账号解锁
if waited_time > 5*60:
account_info[username]['login_fail_nums'] = 0
account_info[username]['lock_time'] = None
# 更新数据到硬盘
write_account_info(account_info)
else:
print(f'account locked, please login after {5*60 - waited_time} s')
continue
# 登录检查
if password == account_info[username]['pwd']:
# 连续三次登录失败才锁定账号
account_info[username]['login_fail_nums'] = 0
write_account_info(account_info)
print('登录成功')
break
else:
# 登录失败,记录失败次数
account_info[username]['login_fail_nums'] += 1
msg = 'wrong username or password, please try again'
if account_info[username]['login_fail_nums'] == 3:
# 记录锁定的那个时刻,时间戳
account_info[username]['lock_time'] = time.time()
msg = 'account locked for max_login_fail_nums exceeded, please login after 5 min'
print(msg)
# 更新数据都硬盘
write_account_info(account_info)
else:
print(f'no account: {username}, please check again')