python复习笔记

一.基础语法

1.基本数据类型

  • 整数
a = 10
print(tyep(a))

python 的 int 类型变量,表示的数据范围没有上限

  • 浮点数
a = 0.5
print(type(a))

只有 float 类型,没有 double,占8个字节

  • 字符串
  • 布尔类型
True 
False

2.算术运算符

有:+ - * / % ** //

  • **

求乘方

print(4**2) # 8
print(4**0.5) # 2
  • //

取整除法(地板除),整数除以整数,还是整数,但舍弃了小数部分,向下取整

print(7//2) # 3.5 -> 3
print(-7//2) # -3.5 -> -4

3.关系运算符

有: < <= > >= == !=

字符串判断大小

使用 == 即可比较字符串内容是否相同。

如果使用大于小于来比较,规则是字典序(按照字母顺序,越前越小)

4.逻辑运算符

and or not 这一系列的运算符称为 逻辑运算符

  • and 相当于Java中的 &&
  • or 相当于 java 中的 ||
  • not 相当于 Java中的 !

5.赋值运算符

= 赋值

a = b = 10
a,b = 10,20 # a = 10
# b=20

两数互换:

a = 10
b = 20
a,b = b,a
print(a) # 20
print(b) # 10

6.复合赋值运算符

复合赋值运算符. 例如 *+= -= = /= %=

7.空语句 pass

a = 1
if a == 1:
    pass
    print("pass")
else:
    print("ss")
# 输出 pass

pass 表示 空语句, 并不会对程序的执行有任何影响, 只是占个位置, 保持 Python 语法格式符合要求

二.函数

1.语法格式

def 函数名(形参列表):
函数体
return 返回值

2.使用函数

例: 求 n~m 之间的和

def listSum(n,m):
    sum = 0
    for i in range(n,m+1):
        sum += i
    return sum

print(listSum(1,3)) # 6

3.返回多个值

除了可以返回单个值之外,还可以返回多个值

def reTuple():
    a = 1
    b = 2
    return a,b

print(reTuple())  # (1, 2)
print(type(reTuple())) # <class 'tuple'>

可以看到,返回的其实是一个 元组 tuple

什么是元组呢,元组其实就是一个有序列表,一旦初始化后不可变

a,b = reTuple() # 等同于 (a,b) = reTuple()
print(a) # 1
print(b) # 2

在语法上,返回一个tuple可以省略括号,而多个变量可以同时接收一个tuple,按位置赋给对应的值,所以,Python的函数返回多值其实就是返回一个tuple,但写起来更方便

4.函数的默认值(默认参数)

def add(x, y, debug=False):
    if debug:
       print(f'调试信息: x={x}, y={y}')
    return x + y
print(add(10, 20)) 
print(add(10, 20, True))

如果第三个参数不传递值,就会使用默认值。需要注意的是,函数的默认值必须在后边,否则会报错。

而且如果有多个默认参数,在调用的时候,默认参数可以不调用,但如果参数位置不对应,是需要指定调用哪个参数的。

def enroll(name,age,gender='女',city='bejing'):
    print('name:',name)
    print('age:',age)
    print('gender:',gender)
    print('city:',city)

enroll('cy',18,'男')
enroll('xb',22,city='guizhou')

# name: cy
# age: 18
# gender: 男
# city: bejing
# name: xb
# age: 22
# gender: 女
# city: guizhou

需要注意的是,定义默认参数时,默认参数必须指向不可变对象

todo

5.关键字参数

如果在传入参数的时候,想不按照顺序来要怎么做呢?

def test(x, y):
    print(f'x = {x}')
    print(f'y = {y}')
test(x=10, y=20)
test(y=100, x=200)

输出:

x = 10
y = 20
x = 200
y = 100

其实就是在传入参数的时候对参数名进行赋值,类似于这样的操作

6.可变参数

可变参数也就是说参数的个数是可变的

def calc(*number):
    sum = 0
    for i in number:
        sum = sum + i
    return sum


print(calc(1, 3)) # 4
print(calc(1,3,5)) # 9
print(calc(1,3,5,7)) # 16

# 如果想传入列表或者tuple
alist = [1,3,5,7]
mytTuple = (1,2,3,4)
print(calc(*alist)) # 16
print(calc(*mytTuple)) # 10

可以看到传入的参数是可变的。为什么参数前面要带*呢?

如果不带*,而是

def calc(number):

那传递的参数就只能是一个了。

而在传递 list 或 tuple 的时候,对应的引用为什么也要加 *呢?

如果不加*,则会报错,或者这样调用:

print(calc(alist[0],alist[1],alist[2]),alist[3])

7.命名关键字参数

对于关键字参数,函数的调用者可以传入任意不受限制的关键字参数。如果想知道传入什么,可以进行检查。

例如:调用一下函数时,检查是否含有 cityjob 参数

def person(name,age,**kw):
  if 'city' in kw:
      print('传递过来的参数含有 city:',kw['city'])

  if 'job' in kw:
      print('传递过来的参数含有 job:',kw['job'])

person('cy',21,city = 'shanghai',job='测试开发')

# 传递过来的参数含有 city: shanghai
# 传递过来的参数含有 job: 测试开发

在调用的时候仍然可以出啊书不受限制的关键字参数,而且可以传入任意的关键字参数,不过必须制定关键字昵称。可以理解为传入的是一个键值对。kw将获得一份 dict

和关键字参数不同,命名关键字参数 **kw 需要一个特殊分隔符**后面的参数被视为命名关键字参数。

三.列表和元组

1.列表

1)创建列表
alist = [1,'python',1.11]
print(alist) # [1, 'python', 1.11]
print(type(alist)) # <class 'list'>
2)通过下标访问
for i in range(len(alist)):
    print(alist[i])
    
输出:
1
python
1.11

直接赋值可以修改

下标取负数,则是指从右往左取值

alist[-2] # python

range(1,11) 相当于list [1,2,3,4,5,6,7,8,9,10]

for循环后面还可以加上if判断,这样我们就可以筛选出仅偶数的平方:

>>> [x * x for x in range(1, 11) if x % 2 == 0]
[4, 16, 36, 64, 100]
3)切片操作

取出子列表

alist = [1,2,3,4]
print(alist[1:2]) # [2] 左闭右开
print(alist[1:]) # [2, 3, 4]
print(alist[:3]) # [1, 2, 3]
print(alist[:]) # [1, 2, 3, 4]
4)新增元素

有两种方式:

alist = [1,'python',1.11]

alist.append(2222)
print(alist) # [1, 'python', 1.11, 2222]

alist.insert(1,'newstr')
print(alist) # [1, 'newstr', 'python', 1.11, 2222]

append() 就相当于 List.add() ,即尾增。

insert() 则是指定下标插入一个元素

5)查找元素
  • 使用 in 操作符,判定元素是否在该列表中

例如要查找 1 是否在这个列表中:

print(1 in alist)  # True
print(2 in alist)  # False
  • 使用 index 方法,查找元素在列表中的对应下标
alist = [11,33,22,44]
print(alist.index(22)) # 2
print(alist.index(66)) # 元素不存在,报错
6)删除元素
7)连接链表

2.元组

元组操作和列表类似,但初始化后是无法修改的

atuple = ()
atuple = tuple()

元组比起列表,有什么优势呢?

  • 元组初始化后无法修改,可以保证数据的安全性
  • 可 hash 的对象,可哈希的对象的前提就是不可变。元组可以作为字典的键,但列表不行。

四.字典

1.创建字典

字典是一种存储键值对的结构

a = {"id":1,'name':'zhangsan'}

print(a) # {'id': 1, 'name': 'zhangsan'}

2.获取 value

查看 key 值是否存在:

print('id' in a) # True
print('score' in a) # False

通过 key 获取 value:

print(a['id']) # 1
print(a['name']) # zhangsan
print(a['score']) # key 值不存在,抛异常

3.操作字典元素

新增/修改元素:

print(a)
a['score'] = 88 # 如果该 key 值不存在,则新增该键值对
print(a)
a['score'] = 90 # 如果存在,则修改对应的 value 值
print(a)

#{'id': 1, 'name': 'zhangsan'}
#{'id': 1, 'name': 'zhangsan', 'score': 88}
#{'id': 1, 'name': 'zhangsan', 'score': 90}

删除元素:

a.pop('score')
print(a) # {'id': 1, 'name': 'zhangsan'}

4.遍历字典

for 循环遍历:

可以获取 key 值,然后通过 key 值来获取 value 值

for key in a:
    print(key,a[key])
# id 1
# name zhangsan

遍历:

# 迭代 key
print(a.keys())
# dict_keys(['id', 'name'])
for key in a.keys():
  print('key:',k)

# 迭代 value
print(a.values())
# dict_values([1, 'zhangsan'])
for value in a.values():
  print('value:',value)

# 同时迭代 key 和 value
print(a.items())
# dict_items([('id', 1), ('name', 'zhangsan')])
for k,v in a.items():
	print(f'{k}:{v}')

5.合法的 key 类型

可哈希的 key 都是合法的,也就是可以计算出一个哈希值。

print(hash(0))
print(hash(3.14))
print(hash('hello'))
print(hash(True))
print(hash(())) # ( ) 是一个空的元组

0
322818021289917443
-1751379255290128896
1
5740354900026072187

而像字典dict和列表list 都是无法计算出哈希值的,也就是不可哈希类型,不可作为 key 值

五.文件

1.什么是文件?

在我们运行一个py程序的时候,变量会把当前的数据保存在内存中,如果程序重启,内存中的数据就会丢失。想要使数据持久化存储,就可以将数据存储到硬盘中,也就是保存在文件中。

2.文件的路径

文件的路径描述的是一个文件所在的位置,通过这个路径就可以定位到这个文件。以 windows为例子,一个文件的路径一般是[盘符] [目录] [文件]

E:\图片\喜欢\QQ图片20221128003530.jpg

像上边的路径:

  • E: 表示的是盘符,不分大小写
  • \ 表示一级目录,当前图片文件是放在 "E 盘"下的"图片"目录的"喜欢"目录底下
1)绝对路径

E:\图片\喜欢\QQ图片20221128003530.jpg就是一个绝对路径,把详细的路径信息描述了出来

2)相对路径

用一个基准目录作为参照点,用. 表示这个基准目录。

例如,我们当前创建一个py项目,那么我们在项目中是以这个项目的根目录作为基准目录的:

在这里插入图片描述

当前的基准目录为:E:\python\api_autotest

然后我们可以用相对路径.cases\customer\test_customer.py来表示 test_customer.py的具体位置。如果是绝对路径则是E:\python\api_autotest\cases\customer\test_customer.py

3.操作文件

E:\test.txt:

这是一个文本文件
1)打开文件
f = open('文件路径','r')
  • 第一个参数是文件的路径
  • 第二个是打开文件的方式。r 表示以只读的方式打开,w表示按照写的方式打开,a 表示按照追加写的方式打开。
  • 返回的是一个文件对象,后续是通过操作这个对象,来操作文件
2)关闭文件

使用close() 来关闭打开的文件

f.close()

文件的打开需要及时的关闭,虽然python有内置的垃圾回收机制,会在文件对象被销毁的时候自动关闭文件。但为了保险起见,仍然要手动关闭,因为垃圾回收操作可能会不及时。

3)写文件
f = open('e:\\test.txt','w')
f.write('hello,world!')
f.close()

打开文件则会发现,当前的内容由"这是一个文本文件"变成了:

hello,world!

也就是写是默认覆盖写的方式

如果不想覆盖掉原来的内容,则可以使用覆盖写的方式:

f = open('e:\\test.txt','a')
f.write('hello,world!')
f.close()

再次打开文件:

hello,world!hello,world!
4)读文件
f = open('e:\\test.txt','r')
print(f.read())
f.close()

返回的是文件所有内容。

可以传入参数,指定获取内容:

f = open('e:\\test.txt','r')
print(f.read(1)) # 读取第一个字符
f.close()
#h

读取行:

如果文件内容是多行文本:

hello world1
hello world2
hello world3

想逐行读取,可以:

f = open('e:\\test.txt','r')
for s in f:
    print(f'line={s}')
f.close()

读取结果:

line=hello world1

line=hello world2

line=hello world3

注:文本文件后边默认跟着换行符"\n"

也可以使用readlines() 方法:

f = open('e:\\test.txt','r')
result = f.readlines()
print(type(result))
print(result)
f.close()
# <class 'list'>
#['hello world1\n', 'hello world2\n', 'hello world3']

返回的是一个list,每一个元素对应指每一行

4.指定字符集

计算机在表示中文的时候,会采取一定的编码方式,即”字符集“

计算机只能表示二进制数据,要想表示英文字母、汉子或者其他的文字符号等,都需要通过编码。

本质是使用数字表示

ASSCII字符编码:使用一个简单的整数就可以表示英文字母和阿拉伯数字。但无法表示汉子,常用的汉字编码方式, 主要是 GBK 和 UTF-8

要保证编码方式统一,才能正常的读取文件内容

打开txt文件,可以看到文件的编码方式:

  • 如果编码是 ANSI , 则表示 GBK 编码.
  • 如果编码是 UTF-8 , 则表示 UTF-8 编码.

指定字符集打开文件:

f = open('d:/test.txt', 'r', encoding='utf8')

关于字符集,参考文章:https://zhuanlan.zhihu.com/p/46216008

5.上下文管理器

虽然知道打开文件后最好要关闭,但还是容易忘记关闭。这时候就可以使用python提供的上下文管理器,来帮助我们解决这个问题。

with open('d:/test.txt', 'r', encoding='utf8') as f:
lines = f.readlines()
print(lines)
  • 使用 with 语句打开文件
  • 当 with 内部的代码块执行完毕,就会自动调用关闭方法f.close()

六.面向对象编程

1.类和实例

类(Class)是抽象的模板,而实例(Instance)是根据类这个模板创建出来的“对象”。

由于类可以起到模板的作用,因此,可以在创建实例的时候,把一些我们认为必须绑定的属性强制填写进去。通过定义一个特殊的__init__方法,在创建实例的时候,就把namescore等属性绑上去:

class Student(object):

    def __init__(self, name, score):
        self.name = name
        self.score = score!

注意到__init__方法的第一个参数永远是self,表示创建的实例本身,因此,在__init__方法内部,就可以把各种属性绑定到self,因为self就指向创建的实例本身。

有了__init__方法,在创建实例的时候,就不能传入空的参数了,必须传入与__init__方法匹配的参数,但self不需要传,Python解释器自己会把实例变量传进去

2.访问限制

如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__,在Python中,实例的变量名如果以__开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问。

class Student(object):

    def __init__(self, name, score):
        self.__name = name
        self.__score = score

    def print_score(self):
        print('%s: %s' % (self.__name, self.__score))

如果外部想要访问 private 权限的字段,可以提供 get 方法,想要修改可以提供 set 方法

		def get_name(self):
        return self.__name

    def get_score(self):
        return self.__score
      
    def set_score(self, score):
        self.__score = score
        
    def set_name(self,name):
      	self.__name = name

需要注意的是,在Python中,变量名类似__xxx__的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是private变量,所以,不能用__name____score__这样的变量名。

3.继承和多态

什么是继承,子类继承父类。子类可以获得父类所有的字段和方法,同时子类也能够拥有自己的字段和方法。

所有类默认继承 object

todo

https://www.liaoxuefeng.com/wiki/1016959663602400/1017497232674368

4.获取对象信息

1)获取类型

使用 type() 方法可以获取到对象的类型

print(type(123))
print(type('123'))
print(type(123.123))
print(type(True))

# <class 'int'>
# <class 'str'>
# <class 'float'>
# <class 'bool'>
2)判断 class 的类型

使用 isinstance() 来判断 class 的类型是否一致

ininstance(class1,class2)

如果一致,返回 True。否则返回 False

isinstance()判断的是一个对象是否是该类型本身,或者位于该类型的父继承链上。

5.实例属性和类属性

由于Python是动态语言,根据类创建的实例可以任意绑定属性。

给实例绑定属性的方法是通过实例变量,或者通过self变量:

class Student(object):
    def __init__(self, name):
        self.name = name

s = Student('Bob')
s.score = 90

但是,如果Student类本身需要绑定一个属性呢?可以直接在class中定义属性,这种属性是类属性,归Student类所有:

class Student(object):
    name = 'Student'

当我们定义了一个类属性后,这个属性虽然归类所有,但类的所有实例都可以访问到。来测试一下:

>>> class Student(object):
...     name = 'Student'
...
>>> s = Student() # 创建实例s
>>> print(s.name) # 打印name属性,因为实例并没有name属性,所以会继续查找class的name属性
Student
>>> print(Student.name) # 打印类的name属性
Student
>>> s.name = 'Michael' # 给实例绑定name属性
>>> print(s.name) # 由于实例属性优先级比类属性高,因此,它会屏蔽掉类的name属性
Michael
>>> print(Student.name) # 但是类属性并未消失,用Student.name仍然可以访问
Student
>>> del s.name # 如果删除实例的name属性
>>> print(s.name) # 再次调用s.name,由于实例的name属性没有找到,类的name属性就显示出来了
Student

从上面的例子可以看出,在编写程序的时候,千万不要对实例属性和类属性使用相同的名字,因为相同名称的实例属性将屏蔽掉类属性,但是当你删除实例属性后,再使用相同的名称,访问到的将是类属性。

结束语: 本文只用于记录学习,参考: 廖雪峰的python教程

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值