Python笔记

笔记对应视频链接:python教程

快捷键

Ctrl + ] 选中的代码行右缩进一个Tab

Ctrl + [ 选中的代码行左缩进一个Tab

Alt + 3 在选中代码行的最左端添加注释符号’##’

Alt + 4 删除选中代码行最左端的注释符号’##’

F5 运行编辑器内的程序文件

pip list 查看以及安装的库

print函数

输出数字:print(222)

输出字符串:print(‘hello’) print(“hello”)

输出表达式:print(2 + 4)

输入文件:

fp = open("F:/test.txt",'a+')
print("hello world",file = fp)
fp.close()

不进行换行输出用逗号隔开:

print('hello','world')

转义字符与原字符

换行:\n

退格:\b

制表符:\t

覆盖符:\r

反斜杠:\

单引号:\’

双引号:\"

原字符:不希望字符串中的转义字符起作用,就使用原字符,就是在字符串之前加上r或者R

print(r'hello\nworld\')	//最后一个不能是反斜线
print(r'hello\nworld\\')

二进制与字符编码

二进制0,1->ASCII->Unicode(几乎包含了全世界的字符,都是用2个字节表示)->utf-8(中文3个字节表示,英文1个字节表示)

print(chr(0b100111001011000)) //打印'乘'print(ord('乘'))	//打印0b100111001011000的十进制20056

标识符和保留字

输出python保留字

import keyword
print(keyword.kwlist)
#['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']

标识符:变量、函数、类、模块和对其它对象起的名字

规则:字母、数字、下划线;不能以数字开头;不能与保留字重名;严格区分大小写

变量的定义和使用

name = '玛利亚'
print('标识',id(name))	#2633937837872
print('类型',type(name))	#<class 'str'>
print('值',name)	#玛利亚

#赋值
name = '杰西卡'	#'玛利亚'被垃圾回收

数据类型

整数类型(int)

n1 = 90
n2 = -76
n3 = 0
#整数可以表示为二进制、十进制、八进制、十六进制
print('十进制',118)
print('二进制',0b10101111)	#175
print('八进制',0o176)	#126
print('十六进制',0x1EAF)	#7855

浮点类型(float)

a = 3.14
print(a,type(a))	#<class 'float'>
n1 = 1.1
n2 = 2.2
print(n1 + n2)	#3.3000000001(有误差)
#增加精度
from decimal import Decimal
print(Decimal('1.1') + Decimal('2,2'))	#3.3

布尔类型(bool)

f1 = True
f2 = False
print(f1,type(f1)) # True <class 'bool'>
#布尔类型可以直接当成整数计算
print(f1 + 1)  #2

字符串类型(str)

str1 = '人生苦短 我用Python'
str2 = "人生苦短"
str3 = '''人生苦短
		我用Python'''
#<class 'str'>

数据类型转换

#str、int、float、bool类型可以相互转换
name = '张三'
age = 20
print('我叫' + name + '今年' + (str)age + '岁')
#我叫张三今年20岁

#str转int,必须是数字串
#float转int,截取整数部分
#str转float,必须是数字串
#int转float,加小数点

注释

单行注释:以’#'开头,直到换行

多行注释:并没有单独的多行注释,将一对三引号之间的代码成为多行注释

中文编码声明注释:在文件开头加上中文声明注释,用以指定源码文件的编码格式 #coding:gbk、#coding:utf-8

输入函数input()

present = input('大圣想要什么礼物?')	#大圣想要什么礼物?定海神针
print(present)	#定海神针
a = input('请输入一个加数:')
b = input('请输入另一个加数')
print((int)a + (int)b)	#或者a = int(input('请输入一个加数:'))

运算符

除法运算(/)

整除运算(//):一正一负向下取整 9//-4 = -3

取余运算(%):一正一负要公式->余数 = 被除数-除数*商

幂运算(**)

赋值运算符(=):a,b,c = 20,30,40 #a = 20, b = 30, c = 40

交换两个变量的值:a,b = b,a

比较运算符:>、<、>=、<=、==、!=

id比较:is #a is not b a的id与b的id是不相等的

布尔运算符:and 、or、not、in #s = ‘hello’ print(‘e’ in s) True

位运算符:位于(&)、位或(|)、左移(<<)、右移(>>)

运算符的优先级

括号>算术运算符>位运算符>比较运算符>布尔运算符>赋值运算符

程序的组织结构

顺序结构:程序语句按顺序执行

对象的布尔值

0、空字符串、列表、元组、字典、集合的布尔值都是False

分支结构

单分支结构 if 条件表达式: 条件执行体

双分支结构 if 条件表达式:条件执行体1 else:条件执行体2

多分支结构 if 条件表达式1:条件执行体1 elif 条件表达式2:条件执行体2 else:条件执行体3

嵌套if

条件表达式

格式 条件执行体1 if 条件表达式 else 条件执行体2

True执行1,False执行2

Pass语句

什么都不做,只是一个占位符,用到需要语句的地方

if ans == ‘yes’:

​ pass

else:

​ pass

range函数

三种创建方式 range(start,stop,step)

1.r = range(10) #查看序列 print(list®) [0,1,2,3,4,5,6,7,8,9]

2.r = range(1,10) #[1,2,3,4,5,6,7,8,9]

3.r = range(1,10,2) #[1,3,5,7,9]

while循环

while 条件表达式:

​ 条件执行体(循环体)

for_in循环

语法结构

for 自定义变量 in 可迭代变量

​ 循环体

如果不需要自定义变量用’_'代替

流程控制语句break和continue

break用于结束循环结构,通常与分支结构一起使用

continue用于结束当前循环

列表

列表对象的id与列表中元素的id都不同

列表的创建方式:1.使用中括号 2.使用内置函数list #obj = list([‘hello’,‘world’,98])

列表的特点:1.列表元素按顺序有序排序

​ 2.索引映射唯一一个数据

​ 3.列表可以存储重复数据

​ 4.任意数据类型可以混存

​ 5.根据需要动态分配和回收内存

列表的查询操作

obj.index(元素) 返回对应的索引,如果有重复,返回第一个,找不到就抛出异常

通过索引:正向[0:N-1] 逆向[-1:-N]

可以通过in、not in来判断元素是否在列表中

获取列表中的多个元素-切片

[start:stop:step] 获得列表的一个拷贝[start, stop)

lis1 = list([1,2,3,4,5])
lis2 = lis1[1:4:1] #lis2 = [2,3,4]

列表元素的增删改操作

在列表的结尾添加一个元素:lst.append(x)

在列表的末尾至少添加一个元素:lst.extend(x) x可以是列表

在列表指定位置添加元素:lst.insert(pos,x)

在任意的位置添加N多个元素:lst[1:] = lst3 #将1到最后的元素替换为lst3的元素

在列表中移除一个元素:lst.remove(x) #或有重复,移除第一个

删除一个指定位置的元素:lst.pop(pos) #不指定参数将删除列表中的最后一个元素

删除至少一个元素,但是将产生一个新的列表对象:new_lst = lst[1:3]

不产生新的列表对象:lst[1:3] = []

清除列表中的所有元素:lst.clear() #直接删除列表

为指定索引的元素赋予新值:lst[pos] = x

为指定的切片赋予新值:lst[1:3] = [300,400,500,500]

列表的排序操作

1.调用sort()方法:lst.sort() #默认升序,降序lst.sort(reverse = True)

2.调用sorted()方法,产生一个新的排序列表:dest_lst = sorted(lst, reverse = True)

lst中的元素顺序不变

列表生成式

lst = [i的表达式 for i in range(1,10)]

字典

Python内置的数据结构之一,与列表一样是个可变序列

以键值对的方式存储数据,字典是一个无序的序列

字典的实现原理与查字典类似,查字典是先根据部首或拼音查找对应的页码,Python中的字典是根据key查找value所在的位置

字典的创建:

1.使用花括号

socres = {'张三':100,'李四':90,'王五':85}

2.用dict()创建

student = dict(name = 'jack',age = 20)
#{'name': 'jack', 'age': 20}

字典中元素的获取:

1.[]

socres = {'张三':100,'李四':90,'王五':85}
print(socres['张三'])	#100
print(socres['陈六'])	#KeyError

2.get()方法

print(sorces['陈六'])	#None

key的判断:

in 或者 not in

socres = {'张三':100,'李四':90,'王五':85}
print('张三' in socres)
print('张三' not in socres)

键值对的删除、清空和添加

del socres['张三']
socres.clear()	#{}
socres['陈六'] = 98

字典的常用操作:

socres = {'张三':100,'李四':90,'王五':85}
keys = socres.keys()	#得到所有键
values = socres.values()	#得到所有值
items = socres.items()	#得到所有键值对

字典元素的遍历:

for item in socres:
    print(socres[item],socres.get(item))

字典的特点:

1.字典中的所有元素都是一个key-value对,key不允许重复,value可以重复

2.字典中的元素是无序的

3.字典中的key必须是不可变对象

4.字典也可以根据需要动态地伸缩

5.字典会浪费较大的内存,是一种使用空间换时间的数据结构

字典生成式:

内置函数zip():用于将可迭代的对象作为参数,将对象中对应的元素打包成一个元组,然后返回由这些元组组成的列表

items = ['Fruits','Books','Others']
prices = [96,78,85]
lst = zip(items, prices)
print(list(lst))
#[('Fruits', 96), ('Books', 78), ('Others', 85)]
d = {item.upper():price for item, price in zip(items,prices)}
print(d)
#{'FRUITS': 96, 'BOOKS': 78, 'OTHERS': 85}

元组

Python内置的数据结构之一,是一个不可变序列(没有增删改操作)

元组的创建方式:

#coding:gbk

t1 = ('Python','world',98)   #或者t = 'Python','world',98
print(t1)	#('Python','world',98)
#只包含一个元素需要使用逗号
t3 = ('Python',)
print(type(t3))	#<class 'tuple'>

t2 = tuple(('Python','world',98))
print(type(t2))	#<class 'tuple'>

将元组设计成不可变序列的原因:

在多任务环境下,同时操作对象时不需要加锁

注意事项: 元组中存储的是对象的引用

​ 1.如果元组中对象本身不可对象,则不能再引用其它对象

​ 2.如果元组中的对象是可变对象,则可变对象的引用不允许改变,但数据可以改变

t = [10,[10,20],50]
t[1].append(30)
print(t)
#[10, [10, 20, 30], 50]	列表是可变序列

元组的遍历:for … in 遍历

t = [10,[10,20],50]
for item in t:
    print(item)

集合

与列表、字典一样都属于可变类型的序列

集合是没有value字典,集合中没有重复元素,集合中的元素是无序的

集合的创建方式:

s = {2,3,4,4}
print(s)	#[2,3,4]
s1 = set(range(6))
print(s1)	#[0,1,2,3,4,5]

集合的相关操作:

#判断操作
s = {2,3,4,5}
print(2 in s)
print(3 not in s)

#新增操作
s.add(8)
print(s)	#{2, 3, 4, 5, 8}
s.update({20,10,1})	#可以放集合、列表、元组
print(s)	#{1, 2, 3, 4, 5, 8, 10, 20}

#删除操作
s.remove(100)	#移除一个元素,没有就KeyError
s.discard(100)	#不会报错误
s.pop()	#删除随机一个元素
s.clear()	#清空集合

集合间的关系:

1.相等(元素是否相同)

2.一个集合是否是另一个集合的子集 s1.issubset(s2)

3.一个集合是否是另一个集合的超集 s1.issuperset(s2)

4.两个集合是否没有交集 s1.isdisjoint(s2) #没有返回True

集合的数学操作:

#coding:gbk

s1 = {10, 20, 50, 40}
s2 = {20, 30, 40, 50, 60}

#交集
print(s1.intersection(s2))
print(s1 & s2)
#{40,50,20}

#并集
print(s1.union(s2))
print(s1 | s2)
#{40, 10, 50, 20, 60, 30}

#差集
print(s1.difference(s2))
print(s1 - s2)
#{10}

#对称差集
print(s1.symmetric_difference(s2))
print(s1 ^ s2)
#{10, 60, 30}

集合生成式:

s = {i * i for i in range(6)}
print(s)	#{0, 1, 4, 9, 16, 25}

字符串

1.字符串的驻留机制

仅保存一份相同且不可变字符串的方法,不同的值被存放在字符串的驻留池中,Python的驻留机制对相同的字符串只保留一份拷贝,后续创建相同字符串时,不会开辟新空间,而是把该字符串的地址赋给新创建的变量

驻留机制的几种情况(交互模式):

(1)字符串的长度为0或1时

(2)符合标识符的字符串

(3)字符串只在编译时进行驻留,而非运行时

(4)[-5,256]之间的整数数字

在需要进行字符串拼接时建议使用str类型的join方法,而非+,因为join()方法是先计算出所有字符串中的长度,然后再拷贝,只new一次对象,效率要比"+"效率高

2.字符串查询操作

s = 'hello, hello'
print(s.index('lo'))    #查找最先出现的目标子串,没找到抛异常
print(s.rindex('lo'))   #查找最后出现的目标子串,没找到抛异常
print(s.find('lo')) #查找最先出现的目标子串,否则返回-1
print(s.rfind('lo'))    #查找最后出现的目标子串,否则返回-1

3.字符串的大小写转换操作的方法

s = 'hello,python'
a = s.upper()   #转化成大写字母后产生一个新的字符串
b = s.lower()   #同理
print(a)    #HELLO,PYTHON
print(b)    #hello,python
print(s)    #hello,python

s2 = s.swapcase()   #大小些互换
print(s2)   #HELLO,PYTHON
s3 = s.title()  #每个单词的首字母大写
print(s3)   #Hello,Python
s4 = s.capitalize() #字符串第一个字母大写
print(s4)   #Hello,python

4.字符串内容对齐操作的方法

s = 'hello,python'
print(s.center(20,'@')) #居中对齐,默认空格字符填充
#@@@@hello,python@@@@
print(s.ljust(20,'#'))  #左对齐,默认空格填充
#hello,python########
print(s.rjust(20,'$'))  #右对齐,默认空格填充
#$$$$$$$$hello,python
print(s.zfill(20))  #右对齐,左边用0填充
#00000000hello,python

5.字符串的劈分

s = 'hello world python'
print(s.split())    #默认空格分割['hello', 'world', 'python']
print(s.split(sep=' ', maxsplit=1))
#指定分隔符和分割数  ['hello', 'world python']
print(s.rsplit())   #从右往左开始分割['hello', 'world', 'python']
print(s.rsplit(sep= ' ',maxsplit=1))    
#['hello world', 'python']

6.字符串的判断方法

#isidentifier()判断字符串是否是合法的标识符
print('hello_world'.isidentifier()) #True
print('12_h'.isidentifier())    #False

#isspace()判断字符串是否全部由空白字符组成(回车、空格、制表符)
print(' \t\n'.isspace())    #True
print('a '.isspace())   #False

#isalpha()判断字符串是否全部由字母组成
print('abs'.isalpha())  #True

#isdecimal()判断字符串是否全部由十进制的 数字组成
print('135'.isdecimal())    #True
print('a24'.isdecimal())    #False

#isnumerica()判断字符串是否全部由数字组成
print('943'.isnumeric())    #True
print('aaa'.isnumeric())    #False

#isalnum()判断字符串是否全部由字母和数字组成
print('a234'.isalnum()) #True

7.字符串的其它操作

s = 'hello Python python'
s1 = s.replace('Python','Java')
print(s1)   #hello Java python

#str.join(iter)方法将一个可迭代对象的元素用指定字符串连接成一个字符串
lst = ['Python','Java','C++']
print('*'.join(lst))
#Python*Java*C++
tup = tuple(lst)
print('|'.join(tup))
#Python|Java|C++
ts = ''.join(lst)
print(ts)   #PythonJavaC++
print('.'.join(ts)) #P.y.t.h.o.n.J.a.v.a.C.+.+

8.字符串的比较操作

print('app' <= 'apple')  #True
print('adc' >= 'bac')    #False
#> < == != >= <=

9.字符串的切片操作

字符串是不可变类型,不具备增删改操作,切片操作将产生新的对象

s = 'hello,Python'
s1 = s[:5:2]
s2 = s[6:]
s3 = s[-6::1]
print(s1)   #hlo
print(s2)   #Python
print(s3)   #Python

10.格式化字符串

#格式化字符串常用的三种方法

name = '张三'
age = 20

#  % 占位符
print('我叫%s 今年%d岁' % (name, age))
# {}占位符
print('我叫{0} 今年{1}岁'.format(name, age))
# f-string
print(f'我叫{name} 今年{age}岁')

#我叫张三 今年20岁

print('%10.3f' % 3.1415926)
#     3.142
print('{0:10.3f}'.format(3.1415926))
#     3.142

11.字符串的编码转换

s = '你好呀'
#编码
print(s.encode(encoding='GBK')) #一个汉字两个字节
print(s.encode(encoding='UTF-8'))   #一个汉字三个字节
#b'\xc4\xe3\xba\xc3\xd1\xbd'
#b'\xe4\xbd\xa0\xe5\xa5\xbd\xe5\x91\x80'

#解码
byte = s.encode(encoding= 'GBK')
print(byte.decode(encoding='GBK'))
#你好呀

函数

1.函数的创建和调用

def calc(a,b):	#a b为形参
    c = a + b
    return c

result =  calc(10,20)	#10 20为实参
print(result)	#30

2.函数的参数传递

#使用了关键字就按名称赋值
def Print(a,b):
    print(a,b)
 
Print(b = 10, a = 20)
#20 10

def fuc(a1, a2):
    print(a1, a2)   #100 ['20', '50']
    a1 = 20
    a2.append('10')

n1 = 100
n2 = ['20','50']
print(n1, n2)   #100 ['20', '50']
fuc(n1, n2)
print(n1, n2)   #100 ['20', '50', '10']
#参数的值是否改变取决于是不是可变对象
#如果函数没有返回值,return可以不用写
#如果返回值是一个,直接返回类型
#函数返回多个对象时,结果为元组
def fun(num):
    odd = []
    even = []
    for i in num:
        if i % 2:
            even.append(i)
        else:
            odd.append(i)
    return odd, even

num = [1,2,3,4,5,6]
res = fun(num)
print(res)
#([2, 4, 6], [1, 3, 5])

3.函数的参数定义

def fun(a, b = 10):
    print(a, b)

fun(100)    #100 10
fun(20,30)  #20 30

print('hello', end = '^^')
#hello^^


#使用*定义个数可变的位置形参,只能定义一个
def fun(*args): #个数可变的位置参数
    print(args)

fun(1,2,3)  #(1, 2, 3)

#使用**定义个数可变的关键字形参,当两者都有时位置形参放在前面
def fun1(**kwargs):
    print(kwargs)

fun1(a = 1, b = 2, c= 3)  #{'a': 1, 'b': 2, 'c': 3}

def func(a, b, c):
    print(a, b, c)

lst = [2,5,6]
func(*lst)  #2 5 6
dic = {'a':12, 'b':13, 'c':14}
func(**dic) #12 13 14

4.异常处理try-except

try:
    a = int(input('输入第一个数'))
    b = int(input('请输入第二个数'))
    print(a/b)
except ZeroDivisionError:
    print('分母不能为零')
except ValueError:
    print('输入了非数字')
else:
    print('无异常')
finally:
    print('无论是否异常都会执行')

常见的异常类型

1.ZeroDivisionError 除(或取模)零(所有数据类型)

2.IndexError 序列中没有此索引(Index)

3.KeyError 映射中没有这个键

4.NameError 未声明/初始化对象(没有属性)

5.SyntaxError Python语法错误

6.ValueError 传入无效的参数

面向对象

1.类的定义

命名规范:首字母大写,其余小写

类的组成:1.类属性 2.实例方法 3.静态方法 4.类方法

#类的定义
class Student:
    native_place = '哈啰' #类属性:类中方法外的变量,被该类的所有对象所共享

    #类的初始化
    def __init__(self, name, age):
        self.name = name
        self.age = age

    #实例方法(类里定义的函数叫做方法)
    def Print(self):
        print(self.name, self.age)

    #静态方法:使用@staticmethod修饰的方法,使用类名直接访问的方法
    @staticmethod
    def method():   #不允许有self
        print('静态方法')

    #类方法:使用@classmethod修饰的方法,使用类名直接访问的方法
    @classmethod
    def fun(cls):
        print('类方法,自带一个cls参数')

2.对象的创建

语法:实例名 = 类名()

stu1 = Student('张三',20)
stu1.Print()    #调用实例方法
Student.Print(stu1) #效果同上
#使用对象的属性
print(stu1.name, stu1.age)
stu1.method()   #静态方法调用
stu1.fun()  #类方法调用

3.动态绑定属性和方法

#类的定义
class Student:
    native_place = '哈啰' #类属性

    #类的初始化
    def __init__(self, name, age):
        self.name = name
        self.age = age

    #实例方法(类里定义的函数叫做方法)
    def Print(self):
        print(self.name, self.age)

def show():
    print('一个函数')

stu1 = Student('张三',20)
stu1.gender = '男'   #动态绑定性别
print(stu1.gender)
stu1.show = show    #动态绑定方法
stu1.show()

4.封装

封装:提高程序的安全性

1.将数据(属性)和行为(方法)包装到类对象中。在方法内部对属性进行操作,在类对象的外部调用方法。这样,无需关心方法内部的具体实现细节,从而隔离了复杂度

2.在Python中没有专门的修饰符用于属性的私有,如果该属性不希望在类对象外部被访问,前边使用两个"_"

class Student:
    def __init__(self, name, age):
        self.name = name
        self.__age = age
    def show(self):
        print(self.name, self.__age)

stu = Student('小明',20)
print(stu.name)
#stu.__age不能在类的外部被使用,可以被实例方法使用
print(dir(stu))
print(stu._Student__age)    #可以通过_类名__属性名访问,不建议

5.继承

语法格式

class 子类命( 父类1,父类2...):
    pass

如果一个类没有继承任何类,则默认继承object

python支持多继承

定义子类时,必须在其构造函数中调用父类的构造函数

#类的定义
class Person(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def show(self):
        print(self.name, self.age)

#类的继承
class Student(Person):
    def __init__(self, name, age, stu_number):
        super().__init__(name, age)
        self.stu_number = stu_number

    def show_stu(self):
        print(self.name, self.age, self.stu_number)

stu = Student('张三',15,135)
stu.show_stu()


#python支持多继承
class A(object):
    pass

class B(object):
    pass

class C(A, B):	#C继承了A和B
    pass

6.方法重写

如果子类对继承自父类的某个属性或方法不满意,可以在子类中对其(方法体)进行重新编写

子类重写后的方法中可以通过super().xxx()调用父类中被重写的方法

#类的定义
class Person(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def show(self):
        print(self.name, self.age)

#类的继承
class Student(Person):
    def __init__(self, name, age, stu_number):
        super().__init__(name, age)
        self.stu_number = stu_number
	#方法重写
    def show(self):
        super(Student, self).show()
        print('学号:',self.stu_number)

stu = Student('张三',15,135)
stu.show()
#张三 15
#学号: 135

7.object类

object类是所有类的父亲,因此所有类都有object类的属性和方法

内置函数dir()可以查看指定对象所有属性

Object有一个____str____()方法,用于返回一个对于"对象的描述",对应于内置函数str()经常用于print()方法,帮我们查看对象的信息,所以我们经常会对____str____()进行重写

#类的定义
class Person(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

    #重写object类的__str__()方法
    def __str__(self):
        return '姓名:{0} 年龄:{1}'.format(self.name, self.age)

    def show(self):
        print(self.name, self.age)

#类的继承
class Student(Person):
    def __init__(self, name, age, stu_number):
        super().__init__(name, age)
        self.stu_number = stu_number

    def show(self):
        super(Student, self).show()
        print('学号:',self.stu_number)

stu = Student('张三',15,135)
print(stu)  #默认调用__str__()方法
#姓名:张三 年龄:15

8.多态

简单地说,多态就是"具有多种形态",它指的是:即便不知道一个变量所引用的对象到底是什么类型,仍然可以通过这个变量调用方法,在运行过程中根据变量所引用对象的类型,动态决定调用哪个对象中的方法。

class Animal(object):
    def eat(self):
        print('动物要吃东西')

class Dog(Animal):
    def eat(self):
        print('狗吃骨头')

class Person(object):
    def eat(self):
        print('人吃饭')

def func(obj):
    obj.eat()

func(Dog())
func(Person())
#狗吃骨头
#人吃饭

静态语言和动态语言关于多态的区别

静态语言实现多态的三个必要条件:

1.继承

2.方法重写

3.父类引用指向子类对象

动态语言的多态崇尚"鸭子类型"当看到一只鸟走起来像鸭子、游泳起来像鸭子、收起来也像鸭子,那么这只鸟就可以被称为鸭子。在鸭子类型中,不需要关心对象是什么类型,到底是不是鸭子,只关心对象的行为

9.特殊方法和特殊属性

特殊属性:
__dict__:获得类对象或实例对象所绑定的所有属性和方法的字典
特殊方法:
__len__():通过重写__len__()方法,让内置函数len()的参数可以是自定义类型
__add__():通过重写__add__()方法,可以用自定义对象具有"+"功能
__new__():用于创建对象
__init__():对创建的对象进行初始化
class A:
    pass

class B:
    pass

class C(A, B):
    def __init__(self, name):
        self.name = name

 #创建C类对象
s = C('Jack')	#s是C类型的实例对象
print(s.__dict__)	#实例对象的属性字典
#{'name': 'Jack'}
print(s.__class__)  #输出对象所属的类型
#<class '__main__.C'>
print(C.__bases__)  #输出C类的父类的元组
#(<class '__main__.A'>, <class '__main__.B'>)
print(C.__mro__)    #查看类的层次结构
#(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
print(A.__subclasses__())   #查看类的子类
#[<class '__main__.C'>]

特殊方法

a = 10
b = 20
c = a.__add__(b)
print(c)

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

    def __add__(self, other):
        return  self.name + other.name

    def __len__(self):
        return len(self.name)

stu1 = Student('Jack')
stu2 = Student('Bob')
s = stu1 + stu2 #s = stu1.__add__(stu2)
#实现了两个对象的加法运算(因为在Student中重写了__add__()方法)
print(s)
#JackBob
print(len(stu1))    #stu1.__len__()
#4

10.__new__ 与__init__演示创建对象的过程

class Person(object):
    def __new__(cls, *args, **kwargs):
        print('__new__被调用执行了,cls的id值为{0}'.format(id(cls)))
        obj = super().__new__(cls)
        print('创建对象的id为:{0}'.format(id(obj)))
        return obj

    def __init__(self, name, age):
        print('__init__被调用了,self的id值为{0}'.format(id(self)))
        self.name = name
        self.age = age

print('object这个类对象的id为:{0}'.format(id(object)))
print('Person这个类对象的id为:{0}'.format(id(Person)))

#创建Person类的实例对象
p1 = Person('张三',20)
print('p1这个Person的实例对象的id为:{0}'.format(id(p1)))
#object这个类对象的id为:8791185532960
#Person这个类对象的id为:39448216
#__new__被调用执行了,cls的id值为39448216
#创建对象的id为:32185096
#__init__被调用了,self的id值为32185096
#p1这个Person的实例对象的id为:32185096

11.类的赋值与浅拷贝

变量的赋值操作

只是形成连个变量,实际上还是指向同一个对象

浅拷贝

Python拷贝一般都是浅拷贝,拷贝时,对象包含的子对象内容不拷贝,因此,源对象与拷贝对象会引用用一个子对象

#类的赋值
class Student(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

stu1 = Student('小明',15)
stu2 = stu1
print(id(stu1), id(stu2))   #指针指向同一个实例对象
#31176328 31176328

#类的浅拷贝
import copy

class Cpu:
    pass

class Disk:
    pass

class Computer:
    def __init__(self, cpu, disk):
        self.cpu = cpu
        self.disk = disk

cpu = Cpu()
disk = Disk()
computer1 = Computer(cpu, disk)
computer2 = copy.copy(computer1)    #对computer1进行浅拷贝:也就是只拷贝当前对象,其子对象不拷贝
print(id(computer1), id(computer1.cpu), id(computer1.disk))
print(id(computer2), id(computer2.cpu), id(computer2.disk))
#35818376 35816136 35816264
#35818120 35816136 35816264

深拷贝

使用copy模块的deepcopy函数,递归拷贝对象中包含的子对象,源对象和拷贝对象所有的子对象也不相同

#深拷贝(不仅拷贝当前对象,其子对象都会拷贝)
computer3 = copy.deepcopy(computer1)
print(id(computer1), id(computer1.cpu), id(computer1.disk))
print(id(computer3), id(computer3.cpu), id(computer3.disk))
#35818376 35816136 35816264
#35840456 35840520 35923784

模块(Moudules)

函数与模块的关系:一个模块中可以包含N多个函数

在Python中一个扩展名为.py的文件就是一个模块

使用模块的好处:

1.方便其它程序和脚本的导入并使用

2.避免函数名和变量名冲突

3.提高代码的可维护性

4.提高代码的可重用性

自定义模块

创建模块:新建一个.py文件,名称尽量不要与Python自带的标准模块名称相同

导入模块:

import 模块名称 [as 别名]			  #导入整个模块
from 模块名称 import 函数/变量/#导入模块中的指定部分
#自定义calc.py模块
def add(x, y):
    return x + y

def div(x, y):
    return (float)(x) / y

#test1.py文件
#导入自定义模块

#方法一
import calc
a = 10
b = 20
c = calc.add(a, b)
d = calc.div(a, b)
print(c, d) #30 0.5

#方法二
from calc import add, div
a = 10
b = 20
c = add(a, b)
d = div(a, b)
print(c, d) #30 0.5

以主程序形式运行

在每个模块的定义中都包含一个记录模块名称的变量__name__,程序可以检查该变量,以确定他们在哪个模块中执行。如果一个模块不是被导入到其它程序中执行,那么它可能在解释器的顶级模块中执行。顶级模块的__name__变量的值为__main__

if __name__ = '__main__':
    pass
#calc2.py
def add(a, b):
    return a + b

if __name__ == '__main__':
    print(add(10, 20))	#只有当点击运行calc2时,才会执行运算
    
#main.py
import calc2
print(calc2.add(100, 200))	#300

Python中的包

包是一个分层次的目录结构,它将一组功能相近的模块组织在同一个目录下

作用:(1)代码规范(2)避免模块名称冲突

包与目录的区别:(1)包含__init__.py文件的目录称为包(2)目录里通常不包含__init__.py文件

包的导入:import 包名.模块名

包的引用:包名.模块名.(函数名、变量名等)

#导入packet1包中的模块
import packet1.module1 as mod1

print(mod1.Abs(-20))

#导入带有包的模块时注意事项
#使用import方式进行导入时,只能跟包名或模块名
#使用from...import...方式可以导入模块名、函数名、变量名

Python中常用的内置模块

sys:与Python解释器及其环境操作相关的标准库

time:提供与时间相关的各种函数的标准库

os:提供了访问操作系统服务功能的标准库

calendar:提供与日期相关的各种函数的标准库

urllib:用于读取来自网上(服务器)的数据标准库

json:用于使用JSON序列化和反序列化对象

re:用于在字符串中执行正则表达式匹配和替换

math:提供标准算术运算函数的标准库

decimal:用于进行精确控制运算精度、有效数位和四舍五入操作的十进制运算

logging:提供了灵活的记录事件、错误、警告和调试信息等日志信息的功能

import sys
import time
import urllib.request
import math
print(sys.getsizeof(24))    #28
print(sys.getsizeof(True))  #28
print(sys.getsizeof(False)) #24
print(time.time())
print(time.localtime(time.time()))
print(urllib.request.urlopen('http://www.baidu.com').read())
print(math.pi)

编码格式

常见的字符编码格式

Python的解释器使用的是Unicode(内存)

.py文件在磁盘上使用UTF-8存储(外存)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-b1vrDX7m-1601649335782)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201002130029286.png)]

文件的读写操作

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0jsCOrYH-1601649335784)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201002130623278.png)]

#tex1.txt	(gbk)
第一行
第二行

#demo1.py

#coding:gbk
f = open('text1.txt','r')   #注意打开文件的编码格式与.py文件的格式是否统一
print(f.readlines())    #['第一行\n', '第二行']
f.close()

常用的文件打开模式

文件类型:按文件中数据的组织形式,文件分为以下两大类

(1)文本文件:存储的是普通"字符"文本,默认为unicode字符集,可以使用记事本程序打开

(2)二进制文件:把数据内容用"字节"进行存储,无法用记事本打开,必须使用专用的软件打开,举例:mp3音频文件,jpg图片,.doc文档等

打开模式:

r:以只读模式打开文件,文件的指针将会放在文件的开头

w:以只写模式打开文件,如果文件不存在则创建,如果文件存在,则覆盖原有内容,文件指针在文件的开头

a:以追加模式打开文件,如果文件不存在则创建,文件指针在文件开头,如果文件存在,则在文件末尾追加内容,文件指针在原文件末尾

b:以二进制方式打开文件,不能单独使用,需要与其它模式一起使用,rb或者wb

+:以读写方式打开文件,不能单独使用,需要与其它模式一起使用,a+

文件对象的常用方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6aFBCVTn-1601649335786)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201002132621910.png)]

with语句(上下文管理器)

with语句可以自动管理上下文资源,不论什么原因跳出with块都能确保文件的正确的关闭,以此来达到释放资源的目的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f8YPg69l-1601649335789)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201002134501635.png)]

#离开with语句,自动释放资源
with open('text1.txt','r') as file:
    print(file.read())

#举例
class Content:
    def __enter__(self):
        print('enter方法被调用了')
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('exit方法被调用了')

    def show(self):
        print('show方法被调用了')

with Content() as  f:   #相当于f = Content()
    f.show()
    
'''
enter方法被调用了
show方法被调用了
exit方法被调用了
'''

os模块操作目录相关函数

getcwd():返回当前的工作目录

listdir(path):返回指定路径下的文件和目录信息

mkdir(path[,mode]):创建目录

makedirs(path1/path2…[,mode]):创建多级目录

rmdir(path):删除目录

removedirs(path1/path2…):删除多级目录

chdir(path):将path设置为当前工作目录

os.path模块操作目录相关函数

abspath(path):用于获取文件目录的绝对路径

exists(path):用于判断文件或目录是否存在,如果存在返回True,否则返回False

join(path, name):将目录 与目录或者文件名拼接起来

splitext():分离文件名和扩展名(返回元组)

basename(path):从一个目录中提取文件名

dirname(path):从一个路径中提取文件路径,不包括文件名

isdir(path):用于判断是否为路径

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Python笔记.md 是一个用于记录Python编程相关内容的markdown文档。 在Python学习过程中,学习者通常会遇到各种问题和疑惑,需要有一个地方来记录学习笔记和重要概念,以方便日后复习和查阅。Python笔记.md 就是一个很好的选择。 Python笔记.md 可以按照自己的需要来组织内容,比如可以分为不同的章节或主题,并使用markdown语法来格式化文档,使其更加清晰易读。 在Python笔记.md中,可以记录Python的基础语法、常用数据结构、函数、类、模块等内容。此外,还可以记录一些常见的错误和解决方法,以便日后遇到类似问题时能够快速找到解决方案。 Python笔记.md 还可以用来记录自己的思考和理解。在学习过程中,我们常常会思考某个概念或代码背后的原理,这时候可以将自己的思考记录在笔记中,以便后续复习和回顾。 使用Python笔记.md 还可以方便与他人分享学习心得。可以在文档中加入注释或标题,使得文档更加易读和友好。同时,也可以将Python笔记.md 推送到版本控制系统中,与他人共享和共同编辑。 总之,Python笔记.md 是一个非常有用的工具,可以帮助学习者系统地记录、整理和复习Python编程相关的知识和经验。无论是初学者还是有经验的开发者,都可以从中受益,并提高自己的编程技能。 ### 回答2: Python笔记.md是一个使用Markdown语法编写的Python笔记文档。Markdown语法是一种轻量级的标记语言,可以快速地编辑和排版文档。 在Python笔记.md中,可以记录Python程序设计的相关知识、概念和技巧。通过使用Markdown语法,可以方便地插入代码块、链接、图片以及其他强调和排版格式,使得笔记更加直观和易读。 Python笔记.md可以按照不同的章节和主题组织内容,方便快速查找和阅读。在每个章节中,可以记录不同的Python编程概念,如数据类型、控制结构、函数、类等。可以通过示例代码和解释说明来详细解释这些概念的用法和特点。 在笔记中,还可以记录一些Python的常见问题和解决方案,例如常见错误、调试技巧等。这些内容可以帮助初学者更好地理解和掌握Python语言。 此外,Python笔记.md还可以连接到其他的Python资源,如官方文档、教程、在线代码编辑器等。这样可以提供更多的学习和参考资料。 总之,Python笔记.md是一个有条理、易读和方便编辑的Python学习笔记文档,可以帮助人们更好地学习和理解Python编程语言。 ### 回答3: Python笔记md是一种用来记录Python编程语言相关内容的文本文件格式。它使用Markdown语法来快速、简洁地编写和格式化笔记Python笔记md的优点是: 1. 简单易懂:Markdown语法简洁明了,使用起来非常简单,即便没有编程背景的人也能快速上手。 2. 跨平台兼容:无论是在Windows、Mac还是Linux系统中,Python笔记md都可以轻松使用。 3. 可读性强:Python笔记md的文本格式使得代码和说明可以同时显示,方便读者理解和学习。 4. 方便分享和发布:Python笔记md可以导出为HTML或PDF格式,方便分享给其他人或者发布到网络上。 5. 与开发工具兼容:大多数集成开发环境(IDE)和文本编辑器都支持Markdown语法,可以实时预览和编辑笔记使用Python笔记md可以帮助程序员记录代码和相关的解释和说明,方便复习和查看。它还可以用于编写技术博客、文档和教育材料等。而且由于其文本格式的特点,Python笔记md也非常适合使用版本控制系统进行版本管理。 总而言之,Python笔记md是一种简单、灵活且易于分享的笔记格式,可以有效提高编程学习和开发的效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值