【Python】基础理论_python理论基础-程序员宅基地

技术标签: python  软件测试全套笔记  

前言

本文主要是Python的基础知识,包括基础定义规则、数据类型、控制结构、函数定义、对象定义、文件对象和异常处理、装饰器编写、多线程和反射方法等。

1 基础定义规则

运行Python的3种方式
交互式解释器中直接运行 命令行方式 编辑器运行(pycharm,vscode等)

1.1 输入输出

input() 接收用户输入,Python3.x后,默认返回值是字符串
print() 打印输出,可以用‘,’分隔参数,默认带回车(换行显示)
‘str’表示字符串,print默认是打印一行,结尾加换行。end=’ '意思是末尾不换行,加空格

a = input("请输入一个数值:")
print("数值结果为:", a)
print("a的数据类型为:", type(a))
print("ab", "cd", sep="*",end="")

1.2 变量规则

1、变量不需要定义类型,类型由赋值给它的数据类型来定义
2、变量在使用前一定要赋值,变量在赋值后才会被创建
3、"="来给变量赋值
变量命名规则
1、第一个字符必须是字母或者是下划线,py文件不要以数字和下划线开头
2、变量名对大小写敏感,首字母大写可以有效避免关键字
3、不要使用保留关键字,如as、and等
4、命名尽量做到顾名思义

1.3 占位符使用

%
%d 整数
%f 浮点数
%s字符串
%% 表示%本身

a = int(input("请输入您的年龄:"))
print("您的年龄是%d岁" % a)
# %f
b = 3.141592653
print("Π的值为%f" % b)
print("Π的值为%.2f" % b)  # 保留2位小数
# %s
print("hello,%s和%s" % ("小明", '小红'))  # 多个占位符
#%% 
print("存活率为%d%%" % 40)  

结果:input返回的是字符串需要转换成数值型的,%%是对%转义

请输入您的年龄:24 
您的年龄是24岁
Π的值为3.141593 
Π的值为3.14 
hello,小明和小红 
存活率为40%

format&f

a = int(input("请输入您的年龄:"))
print("您的年龄是{}岁" .format(a))
b = 3.141592653
print("Π的值为{}".format(b))
print("Π的值为{:.2f}".format(b))  # 保留2位小数
print("hello,{}和{}".format("小明", '小红'))  # 多个占位符
print(f"Π的值为{
      b}")  # f

结果:format支持不指定类型占位,f直接使用变量进行占位

请输入您的年龄:22 
您的年龄是22岁
Π的值为3.141592653 
Π的值为3.14
hello,小明和小红
Π的值为3.141592653

注释
单行注释采用#注释
多行注释使用’‘’‘’'或者是"“”“”"

2.2数据类型

不可变数据类型
不可变数据类型:改变了数据类型值后,就变成新的内存地址,原来的就会释放
不可变类型:数字、字符串、元组

s = 1
print(s)
print(id(s))
s = s + 1
print(s)
print(id(s))

结果:内存地址id值发生了变化

1 
1787650272  # 1的内存地址
 2 
1787650304  # 2的内存地址

可变数据类型
可变数据类型:改变数据的值,不会产生新的变量
可变类型:列表、集合、字典

s = [1, 2, 3]
print(s)
print(id(s))
s.append(4)
print(s)
print(id(s))

结果:

[1, 2, 3] 
2687099754184 
[1, 2, 3, 4] 
2687099754184

2.2.1数值

数值类型:整型(int),浮点型(float),复数(complex)
加减乘除、整除、取余

print(3+2)
print(3-2)
print(3*2)
print(3/2)
print(3//2)
print(3%2)

结果:

5
1 
6
1.5 
1 
1

math中常用的方法
cell 取大于等于X的最小整数值,如果x是个整数就返回X
fabs 返回x的绝对值
floor 取小于等于X的最大整数值,如果x是个整数就返回X
pow 返回x 的y次方,即x**y
sqrt 求x的平方根

import math
print(math.ceil(4.5))
print(math.fabs(-3))
print(math.floor(4.5))
print(math.pow(2, 4))
print(math.sqrt(16))

结果:

5
3.0
4
16.0
4.0

random中常用的方法
random.random():返回[0,1]之间浮点数 左闭右开,随机数可以是0,但不可能是1
random.randint(a,b): 生成a和 b之间的随机整数,也就是[a,b]
rangdom.randrange(a,b): 生成随机整数不包含b,即[a,b)
random.uniform(a,b):生成[a,b之间的随机浮点数
random.choice([]):从列表中随机取出一个元素
random.shuffle([]):打乱列表中元素的顺序
random.sample([],n):从序列中随机取出n个元素

import random
print(random.random())
print(random.randint(1, 10))
print(random.randrange(1, 10))
print(random.uniform(1, 10))
print(random.choice([1, 2, 3, 4]))
a = [1, 2, 3, 4, 5]
random.shuffle(a)
print(a)
print(random.sample(a, 3))

2.2.2字符串

字符串切片
字符串有两个下标,正从0开始,反从-1开始
格式:[startstep]
[:]:从开头到结尾的整个字符串
[start:]:从start提取到结尾
[:end]:从开头到end
[start:end]:从start提取到end
[startstep]

a = "春季是一年的第一个季节"
print(a[:])
print(a[2:])
print(a[:-3])
print(a[2:-3])
print(a[2:-3:2])
print(a[-3:2:-2])

结果:开始值取得到,结束值取不到;步长是正数则从前往后取,负数则从后往前取,且开始值是从后往前 即负数

春季是一年的第一个季节 
是一年的第一个季节
春季是一年的第一 
是一年的第一 
是年第
个第年

转义r

a = r"F:\PycharmProjects\pythonProject\demo.py"
print(a)

结果:可以在\前加\或者是直接在整个前面加 r

F:\PycharmProjects\pythonProject\demo.py

常用方法
len(string):返回字符串长度
count(str,beg = 0,end=len(string)):返回str在string中出现的次数,如果beg或者end指定范,则返回指定范围的次数
capitalize():字符串首个字符大写
find(str,beg = 0,end=len(string)):检查str是否包含在string中,如果是,返回开始索引值,否则返回-1
replace(old, new):将字符串的str1替换成str2
split(str=“”):以str为分隔符拆分字符串,返回字符串拆分后的列表
index(str,beg = 0,end=len(string)):同find 如果str不在字符串中会报一个异常
‘’.join([‘a’,‘b’]):以指定字符串连接后面列表中的字符串元素,以字符串形式返回
isdigit():如果字符串中只包含数字则返回True,否则返回False
isalpha():判断字符串是否只包含字母
islower():如果字符串中包含至少一个区分大小写字符,并且所有这些(区分大小写的)字符都是小写,则返回True,否则返回False
isspace():判断是否只包含空格,是返回True,否则返回False
istitle():判断字符串是否标题化,是返回True,否则返回False
lower():转换字符串中所有大写为小写
upper():转换字符串中所有小写为大写
startswith(str,beg = 0,end=len(string)):判断是否以指定的str开头,是返回True,否则返回False
strip(str):删除字符串两边的str代表字符,如果不指定str则删除空白字符
rstrip(str)和lstrip(str):删除字符串右边或者是左边str代表字符,如果不指定str则删除空白字符

a = "summer is coming"
print(len(a))
print(a.count('m', 3, len(a)-1))
print(a.capitalize())
print(a.find("o"))
print(a.replace('o', 'a'))  # 把o替换成a
print(a.replace(' ', ""))  # 把空格替换成空白
print(a.split(' '))
b = ['summer', 'is', 'coming']
print(' '.join(b))  # 用空格把b连接起来
print(a.isdigit())

结果:

16 		
2 		
Summer is coming 		
 11 		
summer is caming 		
summeriscoming
['summer', 'is', 'coming'] 		
summer is coming 		
False

2.2.3列表(list)

列表是有序的对象集合,可通过索引取值

a = [1, 2, 3, 4, 5, 6]
b = ["hello", "word"]
# 元素修改
print(a[3])
a[3] = 7
print(a)
# 列表 + 连接
c = a + b
print(c)
# 列表删除
del a[3]
print(a)
# 列表清空
b.clear()
print(b)
# 复制,指定的是同一个地址
d = a
a.append(8)
print(a)
print(d)
# 复制,指定不同地址,把a列表值赋给d
d = a[:]
a.append(9)
print(a)
print(d)
d = a.copy()
a.append([10, 11])
print(a)
print(d)
# 嵌套
print(a[7][1])

结果:

4 
[1, 2, 3, 7, 5, 6] 
[1, 2, 3, 7, 5, 6, 'hello', 'word'] 
[1, 2, 3, 5,6] 
[] 
[1, 2, 3, 5, 6, 8] 
[1, 2, 3, 5, 6, 8] 
[1, 2, 3, 5, 6, 8, 9] 
[1,2, 3, 5, 6, 8] 
[1, 2, 3, 5, 6, 8, 9, [10, 11]] 
[1, 2, 3, 5, 6, 8, 9]
11

常用方法
list.append(obj):在列表末尾添加新的对象
list.count(obj):统计某个元素在列表出现的次数
list.extend(seq):在列表末尾一次性追加另一个序列中多个值(用新列表扩展原来的列表)
list.index(obj):从列表中找出某个值第一个匹配项索引位置,索引从0开始
list.insert(index,obj):将对象插入列表
list.pop(index):移除列表中一个元素(默认是最后一个),并返回该元素的值
list.remove(obj):移除列表中某个值的第一个匹配项
list.reverse():反向列表中的元素,倒转
list.sort():对列表中的元素进行排序(无返回值)
max(list):求列表最大值
min(list):求列表最小值
sum(list):对列表求和
len(list):求列表元素个数
list(str):将字符串强制转换成列表
list(range(start,end=none)):快速生成指定范围的数字列表

a = [1, 2, 3, 4, 3]
b = [11, 12, 13]
# list.append
a.append(2)
print(a)
# list.count
print(a.count(3))
# list.extend
a.extend(b)  # 把b中元素加入到a中
print(a)
print(b)
# list.insert
a.insert(3, 23)  # 在索引3添加23数值
print(a)
# list.pop 按照下标移除
a.pop(3)
print(a)
# list.remove   按照元素移除
a.remove(13)
print(a)
# list.reverse
a.reverse()
print(a)
# list.sort
a.sort()  # 从小到大
print(a)
a.sort(reverse=True)  # 从大到小
print(a)
# list(str)
a = list('hello')
print(a)
print(''.join(a))  # 变回字符串
# list(range(start,end=none))
a = list(range(1, 10))
print(a)

结果:

[1, 2, 3, 4, 3, 2] 
2 
[1, 2, 3, 4, 3, 2, 11, 12, 13] 
[11, 12, 13] 
[1,2, 3, 23, 4, 3, 2, 11, 12, 13] 
[1, 2, 3, 4, 3, 2, 11, 12, 13] 
[1, 2,3, 4, 3, 2, 11, 12] 
[12, 11, 2, 3, 4, 3, 2, 1] 
[1, 2, 2, 3, 3, 4, 11,12] 
[12, 11, 4, 3, 3, 2, 2, 1] 
['h', 'e', 'l', 'l', 'o'] 
hello 
[1, 2,3, 4, 5, 6, 7, 8, 9]

2.2.4元组(tuple)

元组一旦初始化,就不再允许被修改,删除
如果元组元素只有一个,必须要在这个元素后面加一个逗号,才会定义为元组

a = ('hello', )
b = ('hello')
print(type(a))
print(type(b))

结果:

<class 'tuple'>
 <class 'str'>

常用方法
len(tuple):计算元组元素个数
max(tuple):返回元组中元素最大值
min(tuple):返回元组中元素最小值
tuple(seq):将列表转换成元组

2.2.5集合(set)

集合无序不重复元素集,主要用于消除重复元素

s = {
    'hello', 1, 2, 3}
print(s)

常用方法
s.add():添加元素
s.remove():删除元素
del(s):删除整个集合,变量一起删除
s.clear():清空集合
len(s):长度计算

s = {
    'hello', 1, 2, 3}
print(s)
# 添加元素
s.add('word')
print(s)
# 删除元素
s.remove(1)
print(s)
# 判断元素是否在集合里面
print('hello' in s)
# 打印集合
for item in s:
    print(item)

结果:无序的,每次结果顺序随机

{1, 2, 3, 'hello'} 
{1, 2, 3, 'hello', 'word'} 
{2, 3, 'hello', 'word'}
True 
2 
3 
hello 
word

2.2.6字典(dictionary)

字典是无序的对象集合,元素通过键值来取值,键不可重复,值可以重复
键只能是不可变数据类型

dic = {
    'name': "liming", 'age': 12}
print(dic['name'])

结果:

liming

常用方法
dict.clear():删除字典中的全部元素
dict.copy():返回一个字典的深复制
dict.fromkeys([]):创建一个以序列seq中的元素作为键的新字典
dict.get(key, default=None):返回指定键的值,如果不在字典中返回default值
dict.update(dict2):把字典dict2的键值对更新到dict中
dict.keys():以列表返回一个字段所有键
dict.values():以列表返回字典中所有值
dict.items():返回字典中键值对列表
dict.popitem():随机删除字典里面任意一项
dict.pop(key):删除指定的键值对

dic1 = {
    'name': "liming", 'age': 12}
dic1.clear()
# dict.copy() 同列表
dic1 = {
    'name': "liming", 'age': 12}
dic2 = dic1
dic2['name'] = 'zhangsan'
print(dic1)
print(dic2)
dic2 = dic1.copy()
dic2['name'] = 'lisi'
print(dic1)
print(dic2)
# dict.fromkeys([])
dic3 = dict.fromkeys(['name', 'id', 'age'])
print(dic3)
# dict.get(key, default=None)
print(dic1['name'])  # 不存在会抛异常
print(dic1.get('name'))  # 不存在返回None
# dict.update(dict2)
dic4 = {
    'class':'math'}
dic2.update(dic4)
print(dic2)
# dict.keys()
print(dic2.keys())
# dict.values()
print(dic2.values())
# dict.items()
print(dic2.items())
# dict.popitem()
dic1.popitem()
print(dic1)
# dict.pop(key)
dic1.pop('name')
print(dic1)

结果:

{'name': 'zhangsan', 'age': 12}
{'name': 'zhangsan', 'age': 12}
{'name': 'zhangsan', 'age': 12} 
{'name': 'lisi', 'age': 12} 
{'name':None, 'id': None, 'age': None} 
zhangsan 
zhangsan 
{'name': 'lisi', 'age': 12, 'class': 'math'}         
dict_keys(['name', 'age', 'class'])
dict_values(['lisi', 12, 'math']) 
dict_items([('name', 'lisi'), ('age', 12), ('class', 'math')]) 
{'name': 'zhangsan'} 
{}

2.3控制结构

顺序结构、判断结构、循环结构

2.3.1判断结构

在python中认为是假(False)的值:None、[]、‘’、0、{}、()

a = 0
if a:
    print("a == 0")
else:
    print("没有执行")

结果:

 没有执行

2.3.2循环结构

python中循环方式分为while和for
for循环一般用在一个已知集合里面进行循环,比如列表、range数字范围内循环
该语句与我们常规认为的if与else搭配迥异。其实质表示为for循环完整执行后才执行else后的语句。如果for循环中遇到break退出,则不执行else后的语句。
while循环一般用在明确知道循环条件的情况
循环和条件嵌套
break 跳出当前循环
continue 结束本次循环,继续下次循环
占位符:pass 语句体pass避免语法错误

for x in a:
    if x == 3:
        break
    print('x的值为:{}'.format(x))ython
在这里插入代码片

结果:

 x的值为:1 
 x的值为:2
a = [1, 2, 3, 4, 5]
for y in a:
    if y == 3:
        continue
    print('y的值为:{}'.format(y))

结果:

y的值为:1 
y的值为:2
y的值为:4 
y的值为:5

2.4函数定义

函数用于将相关功能打包并参数化

2.4.1函数概念

python中有4种不同类型函数
内置函数:python中已经写好的函数,如range,print等
模块函数:一个python模块中导入的函数,如random
自定义函数:自定义函数
嵌套函数:函数中函数

2.4.2函数参数

python定义函数必须使用def关键字,函数名为用户自定义名称
def 函数名(参数列表)
函数体
规则:
1、函数代码块必须使用def关键字开头,后接函数标识符名称和圆括号()
2、任何传入从外部传入函数的参数必须放在函数标识符后面的圆括号中
3、函数第一行语句可选择性的使用文档字符串—用于存放函数说明
4、函数内容以冒号起始,并且缩进。return[表达式]结束函数,选择性返回一个值给调用方
5、不带表达式的return相当于返回None

def add(a, b):  # 形参进行占位
    return a + b  # return返回一个值并且退出当前的函数
print(add(3, 4))   # 实参

结果:7
改变形参的值是否会同时改变实参的值
不可变数据类型,不会;

a = 1
def add(a):
    a = a + 1
    print("形参的值:", a)
add(a)
print("实参的值:", a)

结果:
形参的值: 2
实参的值: 1

可变数据类型。会改变

a = [1, 2, 3]
def add(a):
    a.append(4)
    print("形参的值:", a)
add(a)
print("实参的值:", a)

结果:
形参的值: [1, 2, 3, 4]
实参的值: [1, 2, 3, 4]
常见函数参数
位置参数:实参和形参依据位置一一对应
关键字参数:实参时标明形参的对应关系
默认值参数:函数形参定义声明设置默认值
不定长参数:
(1)加了星号()即args,默认是元组

def printinto(a, *args):
    print("a参数的值为", a)
    print(type(args))
    print(len(args))
    for i in args:
        print(i)
lst = [1, 2, 3, 4]
printinto(1,lst)

结果:
a参数的值为 1
<class ‘tuple’>
1
[1, 2, 3, 4]

def printinto(a, *args):
    print("a参数的值为", a)
    print(type(args))
    print(len(args))
    for i in args:
        print(i)
lst = [1, 2, 3, 4]
printinto(1, *lst)  # lst前的*代表自动解包lst这个列表,使得列表中的每个元素作为函数的参数

结果:
a参数的值为 1
<class ‘tuple’>
4
1
2
3
4
(2)加了星号(**)即*kwargs,默认是字典,也可对字典解包

def printinto(*args, **kwargs):
    for k in kwargs.items():
        print(k)
    for i in args:
        print(i)
printinto(1,2,name="lisi", age=12)

结果:
(‘name’, ‘lisi’)
(‘age’, 12)
1
2

2.4.3函数变量作用域

变量需要先定义在访问
在函数外边的定义属于全局变量
在函数内部的定义属于局部变量
局部变量更改全局变量:global b # 当前使用的变量时全局变量,请不要创建本地变量

2.4.4实战

简单的页面操作
‘’‘1、注册 2、登录 3、查信余额 4、存款 5、取款 6、转账 7、退出’‘’

user_list = [{
    'user': 'zhansan', 'password': '111111', 'balance': 1000},
             {
    'user': 'wangwu', 'password': '222222', 'balance': 2000}]
current_user = None

# 注册页面
def register():
    while True:
        un = input("请填写您的用户名:")
        for item in user_list:
            if un == item['user']:
                print("用户名已存在")
                break
        else:
            pw = input("请输入您的密码:")
            if len(pw) >= 6:
                user_list.append({
    'user': un, 'password': pw, 'balance': 3000})
                print("注册成功")
                return True
            else:
                print("密码有问题,请重新输入")
                while True:
                    pw = input("请输入您的密码:")
                    if len(pw) >= 6:
                        user_list.append({
    'user': un, 'password': pw, 'balance': 3000})
                        print("注册成功")
                        break
                        return True


# 登录页面
def login():
    un = input("请输入您的用户名:")
    pw = input("请输入您的密码:")
    for item in user_list:
        if item['user'] == un and item['password'] == pw:
            print("恭喜您登陆成功")
            global current_user
            current_user = item
            break
    else:
        print("用户名或密码错误")


# 查询余额
def check_balance():
    if current_user:  # 表示当前已登录
        print(current_user['balance'])
    else:
        print("请先登录")


# 存款
def deposit():
    """存款"""
    if current_user:
        money = input("请输入您要存款的金额")
        if money[-2:] == '00' and len(money) > 2:
            current_user['balance'] += int(money)
            print("恭喜存款成功,当前余额为:", current_user['balance'])
        else:
            print("您存款输入方式不对,请检查后重试")
    else:
        print("请先登录")


# 取款
def withdraw():
    """取款"""
    if current_user:
        money = input("请输入您要取款的金额")
        if money[-2:] == '00' and len(money) > 2:
            if current_user['balance'] >= int(money):
                current_user['balance'] -= int(money)
                print("恭喜取款成功,当前余额为:", current_user['balance'])
            else:
                print("您的余额不足")
        else:
            print("您存款输入方式不对,请检查后重试")
    else:
        print("请先登录")


# 转账
def transfer():
    """转账"""
    if current_user:
        to_user = input("请输入对方账号:")
        if current_user['user'] == to_user:
            print("不能给自己转账")
        else:
            for item in user_list:
                if item['user'] == to_user:
                    money = input("请输入您要转账金额:")
                    if money[-2:] == '00' and len(money) > 2:
                        if current_user['balance'] >= int(money):
                            current_user['balance'] -= int(money)
                            item['balance'] += int(money)
                            print("恭喜转账成功,当前余额为:", current_user['balance'])
                        else:
                            print("您的余额不足")
                    else:
                        print("您输入方式不对,请检查后重试")
                    break
            else:
                print("当前账号不存在")

    else:
        print("请先登录")


# 操作
def option():
    menu = '''1、注册 2、登录 3、查信余额 4、存款 5、取款 6、转账 7、退出'''
    while True:
        print(menu)
        option = input("请输入要选择的菜单:")
        if option == '1':
            register()
        elif option == '2':
            login()
        elif option == '3':
            check_balance()
        elif option == '4':
            deposit()
        elif option == '5':
            withdraw()
        elif option == '6':
            transfer()
        elif option == '7':
            print('退出')
        else:
            print("选择菜单错误,请重新选择")

option()

2.4.5包和模块

包和模块的导入
import module
from module import 方法
from module import * # 导入模块的所有东西 弊端可能混淆同名方法变量等
本文件函数优先于导入的函数
关于if name == ‘main’:语句作用:
__name__属性是每个py文件的内置属性,当这个文件是被直接执行时, name__属性值为__main。如果被作为一个包被导入到其他文件中使用时,__name__属性值会变成文件名。所以我们可以利用者的特性来判断当前文件使用方式,从而执行特定代码

2.5对象定义

2.5.1基本定义

面向过程:做一件事,需要按照什么样的过程完成
面向对象:讲一件事情想象成一个对象,然后通过提取该对象所有共同的方法和属性,利用这些方法和属性来完成这件事情的方法。
意义:面向对象编程以对象作为程序的基本单元,将方法和数据封装其中,它具有继承、封装、多态三大特性,可以大大提高软件重用性、灵活性和扩展性。

2.5.2基本特性

类:具有相同属性和方法的对象的总称
对象:类的一个实例叫做对象
python里面自定义了一个终极父类:object,进行默认
实例方法
只能由类实例,也就是对象来调用,第一个参数总是self,调用时由python自动传入当前调用该方法的实例
self作用:定义方法时表明当前方法是一个实例方法,只能由类的实例来调用
self定义方法时必须要以第一个参数的形式定义到实例方法中,但是进行调用时不需要写self参数
类方法
使用@class method 来修饰,类方法默认以cls参数作为第一个参数,调用时可以以类直接进行调用,也可以以实例来调用。实例权限大于类的权限但是类方法不能访问对象属性(即通过瑟利夫.xxx定义的属性),只能访问类属性
区别
类方法:和具体的实例没有关系,一般定义成类方法,由类型进行调用;比如说是math模块的方法
实例方法:和某个实例有关,每个实例可能有不一样的方法,定义为实例方法,由实例进行访问
属性方法
可以像属性一样进行调用的方法,目的是防止直接对属性的值进行修改
类属性:能被类和实例方法访问
实例属性:self 只能实例访问

class Student:
    def __init__(self, name, age, sid):  # init方法在初始化一个类的实例的时候自动被调用
        self.name = name
        self.age = age
        self.sid = sid

    def study(self):  # self代表当前这个方法是一个实例方法,只能由student类的实例来调用
        print('{}爱学习!'.format(self.name))

    @classmethod
    def ranning(self):
        print("小明在跑步!")
# 面向对象里面对象的方法不能直接调用,只能通过类或者是实例进行调用
'''通过实例调用'''
stu = Student('lisi', 15, 'S001')
stu.study()
'''通过类名调用'''
stu.ranning()

2.5.3继承特性

注意 :
子类与父类重名,子类覆盖父类
子类init时需显示调用父类init

# 继承
class RichMan:

    def __init__(self, money, company):
        self.money = money
        self.company = company

    def earn_money(self, number):
        self.number = number

    def spend_money(self, number):
        self.number = number

    def show_money(self):
        print('Rich man has' + str(self.money))


class RichChild(RichMan):  # 表示继承于RichMan
    def __init__(self, money, company, ):  # 当子类定义自己的init方法时,务必要先显示调用父类的init方法,否则父类会初始化失败
        super().__init__(money, company)  # 显示调用父类的init方法,确保父类初始化成功
        self.own_money = 0

    def earn_money(self, number):  # 子类定义和父类同名时,子类方法覆盖父类方法
        self.number = number
        self.own_money += self.number

    def spend_money(self, number):
        self.number = number
        if self.own_money == 0:
            self.money -= number
        else:
            if number <= self.own_money:
                self.own_money -= number
            else:
                self.money -= (number - self.own_money)
                self.own_money = 0

    def show_money(self):
        if self.own_money > 0:
            print('RichChile man has' + str(self.own_money))
        else:
            print('my father has', self.money)

    def show_my_money(self):
        print('RichChile man has' + str(self.own_money))


rc = RichChild(1000, 8)
print('有多少钱', rc.money)
print('有多少公司', rc.company)
print('起始金额:', rc.own_money)
rc.earn_money(500)
print(rc.own_money)

2.6文件对象和异常处理

2.6.1文件对象

python操作文件基本语法格式 :
with open(r‘文件路径’,mode=‘文件操作模式’)as f:
文件具体操作代码
注意:
1、其中变量名f是指向打开文件的句柄(可以是任意替换为其他有效变量名)
2、文件路径可以是相对路径,也可以是绝对路径。
3、open方法只能用于读取txt、csv等文本文件,不能读取word、excel等第三方文件,第三方文件必须用专门的库才能操作
常用文本文件读写模式
r 读模式只能进行读操作,不能进行写操作,而且文件必须事先存在,否则会报找不到文件异常。默认就是r模式
w 写模式,只能进行写操作,不能进行r操作。如果用w模式打开已经存在的文件,会立即清空以前文件内容。如果要打开文件不存在,会自动创建新的文件
a 追加写模式,只能写操作,不能读操作,但是在文件尾部追加新的内容。文件可以事先不存在。
常用文件读取方式
f.read() #一次性读取所有文件nr
f.read(100) # 读取参数指定的字符长度
f.readline() # 读取一行内容,如果指定数字则只读取一行中指定的字符数
f.readlines() # 按行读取全部内容到一个表中
for line in f: # 直接通过一个循环来读取文件
绝对路径,需要有demo.txt文件,文件中有中文的时候,需要加上encoding = ‘utf8’,防止乱码

with open(r'demo.txt', mode= 'r', encoding = 'utf8') as f:
    # print(f.read())  # 所有的内容
    # print(f.read(2))  # 前两个字符
    # print(f.readline())  # 读一行
    print(f.readlines()[0])   # 返回列表,取第一行

f.write(”要写入的字符串“):以字符串形式写入,不会换行,需要自己在字符串末尾加上\n来换行
f.writelines(list_of_text_strings):以列表写入,再写入大量内容时,调用writelines写入多行在性能上会比使用write一次性写入要高

2.6.2异常处理

# 异常处理
'''代码原则
1、except语句不是必须的,finally语句也不是必须的,但是两者必须要有一个,否则就没有try的意义了。
2、except语句可以有多个,python会按照except语句的顺序依次匹配指定的异常,如果异常已经处理就不会再进入后面的except语句。
3、except语句可以以元组形式同时指定多个异常
4、except语句后面如果不指定异常类型,则默认捕获所有异常
5、只要有finally语句,不管有没有异常,finally里面的代码都会执行'''
try:   # 可能出现异常的代码
    pass
except '异常类型1':
    '异常类型1的处理代码'
except '异常类型2' as e:
    '异常类型2的处理代码'
except '异常类型N':
    '异常类型N的处理代码'
except:
    '其他未知异常的处理代码'
finally:
    '异常处理结束后要执行的代码'
# 实例 输入字符报错,然后再输入数字
while True:
    a = input("请输入一个数字:")
    try:
        num = int(a)
        break
    except ValueError:
        print('请输入有效的十进制数字')
    finally:
        print('进入finally')

2.7装饰器编写

2.7.1基本概念

用于装饰其他函数的函数,即为其他函数添加特定功能或约束的函数(在python中装饰器都是以@符号开头)
装饰器两个原则
1、装饰器不能修改被装饰函数源码
2、装饰器不能修改被装饰函数的调用方式
函数即变量
函数名和变量名一样,只是一个变量的标识符,它指向函数定义的内存地址。
在函数定义中去调用其他函数时,并不会立即调用该函数
在执行一个调用了其他函数的函数时,如果在内存中没有找到被调用函数的定义,则会程序报错

def doo():
    print("hello word")
a = doo  # 如果函数名上面加了括号,则表明执行该函数;如果函数名后面没有括号,则表示是对该函数的一个引用
doo()
a()

高阶函数
符合下列条件之一就是高阶函数:
接受函数名作为形参
返回值中包含函数名

# 高阶函数
def foo():
    sum = 0
    for i in range(100000):
        sum += i
    print(sum)
import time
def too(a):
    start_time = time.time()  # 记录开始时间
    a()  # 调用传入参数
    end_time = time.time()  # 记录结束时间
    print('运行时间为:', end_time - start_time)
too(foo)

嵌套函数

# 嵌套函数
import time

def poo(a):
    def too():
        start_time = time.time()  # 记录开始时间
        a()  # 调用传入参数
        end_time = time.time()  # 记录结束时间
        print('运行时间为:', end_time - start_time)
    return too

@poo  # 为了方便大家使用装饰器,专门定义的装饰器语法糖 和foo = poo(foo)效果一样
def foo():
    sum = 0
    for i in range(100000):
        sum += i
    print(sum)

# foo = poo(foo)
foo()

装饰器=高阶函数+嵌套函数
装饰器基本编写套路
1、第一步:定义一个接受函数名作为参数的高阶函数
2、第二步:在高阶函数中定义一个嵌套函数,在该嵌套函数中
封装想要添加的功能代码
调用作为参数传入的函数名
返回嵌套函数的函数名

2.8多线程

线程和进程的基本概念
简单说,进程是资源分配的最小单位,线程是CPU调度的最小单位

import threading  # 多线程模块
import time
namelist = ['zhanshan', 'lisi', 'wangwu']
def action(content):
    for item in content:        print(threading.current_thread().getName() + item)  #获取当前线程和名字
        time.sleep(1)
for i in range(1,4):
    # 参数必须以元组形式传入,如果只有一个参数,必须打上逗号
    t = threading.Thread(target=action, args=(namelist,))
    t.start() # 启动线程
print('主线程结束')

线程常用方法
join方法:用于阻塞主线程,等子线程运行完成后在运行主线程(主线程等待子线程)

import threading  # 多线程模块
import time
namelist = ['zhanshan', 'lisi', 'wangwu']
def action(content):
    for item in content:
        print(threading.current_thread().getName() + item)  #获取当前线程和名字
        time.sleep(1)
threads = []

for i in range(1,4):
    # 参数必须以元组形式传入,如果只有一个参数,必须打上逗号
    t = threading.Thread(target=action, args=(namelist,))
    t.start() # 启动线程
    # t.join()  # 不能直接放这里,每次都会会阻塞主线程
    threads.append(t)

for t in threads:
    t.join()
print('所有工作结束')

setDaemon方法:主线程结束,子线程也必须跟着结束

import threading  # 多线程模块
import time
namelist = ['zhanshan', 'lisi', 'wangwu']
def action(content):
    for item in content:
        print(threading.current_thread().getName() + item)  #获取当前线程和名字
        time.sleep(1)

for i in range(1,4):
    # 参数必须以元组形式传入,如果只有一个参数,必须打上逗号
    t = threading.Thread(target=action, args=(namelist,))
    t.setDaemon(daemonic=True)
    t.start() # 启动线程
print('所有工作结束')

2.9反射方法

基本概念
通过字符串的形式在运行时动态改变程序的变量、方法及属性的操作。注意,对于反射操作中所有的修改都会在内存中进行,所以它并不会实际修改代码。主要目的是提高代码在运行时的灵活性
常用方法
hasattr:输入一个字符串,判断对象有没有这个方法或属性
getattr:获取对象属性值或方法的引用。如果是方法,则返回方法的引用,如果是属性,直接返回属性值。如果该属性或方法不存在,则抛出异常

class Dog:
    def __init__(self, name):
        self.name = name
    def eat(self):
        print('{}正在吃东西'.format(self.name))

    def sleep(self):
        print('{}正在吃睡觉'.format(self.name))
dog = Dog('花花')
func = input('请输入您要执行的方法名:')
if hasattr(dog, func):
    try:
        getattr(dog, func)()  # getattr返回的是一个方法名
    except TypeError:
        print(getattr(dog, func))
else:
    print('不存在')
# if func == 'eat':
#     dog.eat()
# elif func == 'sleep':
#     dog.sleep( )
# else:
#     print('不存在')

setattr:动态添加一个方法或属性
delattr:动态删除一个方法或属性

class Dog:
    def __init__(self, name):
        self.name = name
    def eat(self):
        print('{}正在吃东西'.format(self.name))

    def sleep(self):
        print('{}正在吃睡觉'.format(self.name))
dog = Dog('花花')
# 绑定属性
print(dir(dog))
attr_name = input('请输入一个属性名')
attr_value = input('请输入一个属性值')
setattr(dog, attr_name, attr_value)
print(dir(dog))
print('狗狗年龄为: ', getattr(dog, attr_name))
# 绑定方法
def talk(txt):
    print('花花说{}'.format(txt))
method = input('请输入要绑定的方法名:')
setattr(dog, method, talk)
print(dir(dog))
getattr(dog, method)('今天天气不错')
# 删除方法
delattr(dog, method)
getattr(dog, method)('今天天气不错')
print(dir(dog))

总结

对于我自己来说需要记住的是:
1、占位符使用
2、数据类型:数值、字符串、列表、元组、集合、字典;其中字符串、列表、集合、字典需多关注
3、控制结构需要关注判断和循环之间的嵌套使用
4、了解函数定义,能够进行调用
5、对象基本特性,关注继承特性

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_46430149/article/details/123974962

智能推荐

dart 引入库、第三方库_pub库的第三方资源怎么安装在dart中-程序员宅基地

文章浏览阅读1.5k次。系统内置库import 'dart:math'import 'dart:io'import 'dart:convert'Pub包管理系统中的库需要取flutter库中查找所需要的库,按文档下载使用 使用: 1、根目录创建pubspec.yaml,并配置名称、描述和依赖 无引号 name:, version:, descript..._pub库的第三方资源怎么安装在dart中

matlab gui 保存文件,Matlab GUI的文件打開和保存uigetfile uigetdir-程序员宅基地

文章浏览阅读735次。1.uigetfile文件打開對話框(1)方式調用格式:[FileName,PathName,FilterIndex]=uigetfile[FileName,PathName,FilterIndex]=uigetfile('FileSpec')FileName,PathName,FilterIndex]=uigetfile('FileSpec','DialogTitile','DefaultNa..._matlabgui界面打开文件夹

something-something-V2下载及解压_cat 20bn-something-something-v2-?? | tar -xvzf –-程序员宅基地

文章浏览阅读4.2k次。something-something之前一直下不下来,可能是vpn的问题。不过如果下载时间过长,页面就需要重新刷新,原来的下载链接就会失效,所以最好一次只下一部分。下载完之后按照页面https://20bn.com/datasets/download给出的命令cat 20bn-something-something-v2-?? | tar zx提取压缩文件,但是执行解压缩命令时一直提示gzip: stdin: not in gzip formattar: Child return_cat 20bn-something-something-v2-?? | tar -xvzf –

VS2019编译3D slicer 5.3.0成功_slicer启动调试时找不到ctkwidgets.dll-程序员宅基地

文章浏览阅读269次。进入了子文件夹Slicer-build中,如果直接用VS打开Slicer.sln会遇到 缺少QT5widgets.dll,缺少CTKwidget.dll等各种问题_slicer启动调试时找不到ctkwidgets.dll

java中浮点数的比较_使用如下语句进行浮点数的比较。system.out.println(math.abs(a-b)<1e-程序员宅基地

文章浏览阅读411次。java中浮点数的比较不能用“==”直接比较原因:float和double类型都不能用于严格要求精度的计算,这是因为float和double类型使用的都是IEEE 754标准,而这种标准的表示范围和表示精度有限,根据标准,将不能表示的范围舍去。所以,任何整数都可以通过二进制表达出来,但是小数往往不能通过二进制精确表达。具体比较方法1.Math.abs (a-b)<1e-62.BigDeimal方法具体实现:public class Main { public static v_使用如下语句进行浮点数的比较。system.out.println(math.abs(a-b)<1e-6);

java操作x509数字证书_x509cert jar包-程序员宅基地

文章浏览阅读1.8w次,点赞4次,收藏20次。openssl 自建ca,颁发客户端证书 前一篇介绍了非对称加密,数字证书,ca等概念之后,剩下的就是一些实战了java操作x509数字证书一般我们自建了ca系统之后,就要颁发给客户端使用,当然证书用途很多了,例如,加密解密,签名验签等这些最原理性的使用,应用场景就比较多了,例如电子签章,数据指纹,生物识别,电商,支付安全等等都使用到了数字证书,例如有些政府部门做的内部身份认证系统,与设备,生物识_x509cert jar包

随便推点

苹果端手机微信页面长按图片无法保存的解决方案_微信公众号长ios按保存图片不生效-程序员宅基地

文章浏览阅读3.9k次。苹果端手机微信页面长按图片无法保存的解决方案_微信公众号长ios按保存图片不生效

KDD基准系统描述_kdd论文作者预测authoridpaperid-程序员宅基地

文章浏览阅读639次。目录介绍KDD_Benchmark:基准系统目录,根目录 1 data:数据目录,仅包含dataset 1.1 train_set:训练集文件夹 1.1.1 Train.authorIds.txt:训练集的所有作者列表,每一行为一个作者id 1.1.2 Train.csv:训练集。第一行为表头:AuthorId,ConfirmedPaperIds,DeletedPaperIds。后面每行为对_kdd论文作者预测authoridpaperid

java1.7与1.8对比_JDK1.8与1.7的区别-程序员宅基地

文章浏览阅读1.8k次。转自:http://www.2cto.com/kf/201307/225968.html本文是我学习了解了jdk7和jdk8的一些新特性的一些资料,有兴趣的大家可以浏览下下面的内容。官方文档:http://www.oracle.com/technetwork/java/javase/jdk7-relnotes-418459.html在jdk7的新特性方面主要有下面几方面的增强:1.jdk7语法上1..._class对象1.7与1.8的位置

C#调用科诚(Godex)打印机(快速二次开发)_c#科城打印机标签模板-程序员宅基地

文章浏览阅读1.8k次。C#调用科诚(Godex)打印机(快速二次开发)首先去Godex官网下载GoLabel软件 首先创建模板,添加变数等等(这里字体要用打印机内建字型),具体看Golabel文档,内建字型不支持打印汉字,需要选择向量字体,然后下载使用。右边为模版生成后的指令,模板生成之后下载至打印机。下一步就是代码调用这个模板,GoLabel指令有调用方法,具体就是:^Kname (name为保存至打印机的模板名称)xxxx(为具体发送的内容,有几个变量..._c#科城打印机标签模板

问卷调查:自定义表单设计vue_vue 调察问卷插件-程序员宅基地

文章浏览阅读4.2k次,点赞6次,收藏22次。由于公司业务需求,做自定义满意度问卷调查,在线上找插件不尽如人意(插入文件多,ui不好改);自家业务比较简单;种种原因,于是花一点时间开发简单的表单设计页面。于此记录开发过程首先看看预览效果,传送地址:http://fanfan18.gitee.io/customize-form-by-vue/纯vue开发,无jQuery,数据驱动页面。引入文件:iconfont 图标文件,vu..._vue 调察问卷插件

linux安装不同版本的tensorflow_linux切换tensorflow 版本-程序员宅基地

文章浏览阅读3k次。不同的python版本,安装不同的tensorflow版本Python3.5.#pip install https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-1.4.0-cp35-cp35m-linux_x86_64.whl(CPU)pip install https://storage.googleapis.co..._linux切换tensorflow 版本

推荐文章

热门文章

相关标签