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')
posted @ 2020-03-04 14:08  the3times  阅读(365)  评论(0编辑  收藏  举报