Python常用语法


本文旨在记录笔者在日常使用Python中经常用到的一些语法,不间断更新,其中部分引用到知乎、CSDN等途径的一些参考资料,如有雷同请见谅,并私信笔者进行沟通。

1.字符串(str)

1.1.添加

1.直接相加
2.中心对齐填充

str0.center(width, fillchar)#返回一个指定的宽度 width 居中的字符串,fillchar 为填充的字符,默认为空格。

3.左对齐填充

str0.ljust(width[, fillchar])#返回一个原字符串左对齐,长度width的新字符串,fillchar为填充字符,默认为空格。

4.右对齐填充

str0.rjust(width,[, fillchar])#返回一个原字符串右对齐,长度width的新字符串,fillchar为填充字符,默认为空格

1.2.删除

1.循环删除右侧指定字符

str0.rstrip(chars)#删除字符串右侧指定字符char(所有),默认删除空白符(包括'\n', '\r',  '\t',  ' ')

2.循环删除左侧指定字符

str0.lstrip(chars)

#删除字符串左侧指定字符
3.循环删除左右侧指定字符
str0.strip(chars)#删除字符串左右侧指定字符
比如:

str0 = "88888888this is string example....wow!!!8888888";
print(str0.rstrip('8'))#88888888this is string example....wow!!!

1.3.检索

str0.find(str, beg, end)#检测 str0 是否在字符串beg到end范围中,如果是返回第一次出现的索引值,否则返回-1,默认全部范围
str0.rfind(str, beg, end)#从右开始查找,索引顺序与原字符串符合
str0.index(str, beg, end)#跟find()方法一样,只不过如果str不在字符串中会报一个异常。
str0.rindex(str, beg, end)#从右开始查找,索引顺序与原字符串符合

1.4.统计

str0.count(str, beg,end)#返回 str0 在 string 里面beg到end范围出现的次数,默认全部范围

1.5.列表字符串相互转换

1.5.1.列表->字符串

list0=['1', '2', '3', '4', '5']
str0=' '.join(list0)#用于将序列list0中的元素以指定的字符' '连接生成一个新的字符串
print(str0)#'12345'

1.5.2.字符串->列表

1.直接转换

str0 = "12345"
list0 = list(str0)
print(list0)#['1', '2', '3', '4', '5']

2.按元素分割

str0.split(char, num)#char:分隔符,默认为所有的空字符,包括空格、换行(\n)、制表符(\t)等。num:分割次数,默认为-1分隔所有。

比如:

str0 = "www.google.com"
list0 = str0.split(".")
print(list0)#['www', 'google', 'com']

3.按行分割

str0.splitlines(keepends)#按照行('\r', '\r\n', \n')分隔,返回一个包含各行作为元素的列表,如果参数 keepends 为 False,不包含换行符,如果为 True,则保留换行符。

比如:

'abc\n\ndefg\rkl\r\n'.splitlines()		#['abc', '', 'defg', 'kl']
'abc\n\ndefg\rkl\r\n'.splitlines(True)	#['abc\n', '\n', 'defg\r', 'kl\r\n']

1.6.大小写

1.小写

str0.lower()#转换字符串str0中所有大写字符为小写。

2.大写

str0.upper()#转换字符串str中的小写字母为大写。

3.第一个字符大写

str0.capitalize()#将字符串str的第一个字符转换为大写

4.标题化

str0.title()#将str0返回"标题化"的字符串,就是说所有单词都是以大写开始,其余字母均为小写

比如:

str0 = "this is string example from runoob....wow!!!"
print (str0.title())#This Is String Example From Runoob....Wow!!!

1.7.判断

1.数字判断

str0.isdigit()#若字符串只包含数字则返回True 否则返回False。

2.大小写判断

str0.islower()#若字符串str至少有一个字符且所有字符都为小写则返回 True,否则返回 False。
str0.isupper()#若字符串str至少有一个字符且所有字符都为大写则返回 True,否则返回 False。

3.空白判断

str0.isspace()#若字符串中只包含空白,则返回 True,否则返回 False。

4.标题判断

str0.istitle()#若字符串是标题化的(见 title())则返回 True,否则返回 False。

1.8.替换

str0.replace(old, new [, max])#把将字符串中的 old 替换成 new,如果 max 指定,则替换不超过 max 次。

2.列表(list)

2.1.添加

1.扩充多个元素

list0.extend([seq])#在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)

2.插入

list0.insert(index, element)#将对象插入列表

3.直接相加实现拼接

2.2.删除列表元素

1.根据索引

del list0[index] 

2.根据元素值

list0.remove(element)#删除第一个匹配项

3.弹出

element=list0.pop(index=-1)#移除列表中一个元素(默认最后一个),并且返回该元素的值

2.3.检索

list0.index(element)#从列表中找出某个值第一个匹配项的索引位置,找不到则报错

2.4.统计

list0.count(element)#统计某个元素在列表中出现的次数

2.5.提取序列(字符串,列表等)中合格元素

filter(function, iterable)#function:判断函数,返回值为真或假。iterable:可迭代对象。

过滤出列表中的所有奇数

newlist = list(filter(lambda x:x%2==1, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]))#filter为指针,需用list转换为列表[1, 3, 5, 7, 9]

过滤出字符串中的所有数字

newlist=list(filter(lambda x,x.isdigit(), '123ab45'))#filter为指针,需用list转换为列表['1', '2', '3', '4', '5']

2.6.列表赋值

1.单个赋值

x=[[0 for i in range(2)] for i in range(3)]#[[0, 0], [0, 0], [0, 0]]
x[1][1]=1#[[0, 0], [0, 1], [0, 0]]

Matrix = [[] for x in range(3)]#[[], [], []]

2.整体赋值

x=[[0]*2]*3#改动一个,一列全改
x[1][1]=1#[[0, 1], [0, 1], [0, 1]]

3.切片

list0[1,2]#不对,应
list0[1][2]

2.7.颠倒

list0.reverse()#反向列表中元素

2.8.排序

list0.sort( key=None, reverse=False)#key函数筛选参加排序的元素。reverse=True 降序,False升序

比如:

random = [(2, 2), (3, 4), (4, 1), (1, 3)] 
random.sort(key=lambda element:element[1])#指定第二个元素排序
#[(4, 1), (2, 2), (1, 3), (3, 4)]

2.9.映射

list(map(lambda x: x ** 2, [1, 2, 3, 4, 5]))#[1, 4, 9, 16, 25]

3.堆和list类似

4.队列和list类似,比list多一些功能

from collections import deque
dlist=deque([1,'a'])

4.1.添加

dlist.append('b') # 在末尾加数据[1,'a', 'b']
dlist.appendleft(0) # 在最前端插入数据#[0,1,'a', 'b']
dlist.extend(['c','d']) # 在末尾追加list 数据#[0,1,'a', 'b','c','d']
dlist.extendleft([-2,-1])# 在前端插入list 数据[-2,-1,0,1,'a', 'b','c','d']

4.2.删除

dlist.pop() # 删除末尾的数据#[-2,-1,0,1,'a', 'b','c']
dlist.popleft() # 删除最前端的数据#[-1,0,1,'a', 'b','c']

4.3.批量移动

dlist.rotate(-2)#将左端的前两个元素移动到右端
print(dlist)#[1, 'a', 'b', 'c', -1, 0]
dlist.rotate(2) # 将右端的后两个元素移动到左端
print(dlist)#[-1, 0, 1, 'a', 'b', 'c']

5.元组(tuple)

5.1.添加

1.直接相加
2.拼接

x=((1)*4)*2#((‘1’,’1’,’1’,’1’),(‘1’,’1’,’1’,’1’))
#引用与列表类似,并可多维,但不能修改值

6.字典(dict)

6.1.添加**

1.初始化
a={} 字典 可以a[1]=1
a=[] 列表 不可以a[1]=1
2.批量创建

dict.fromkeys(seq[,value])#创建一个新字典,以列表seq中元素做字典的键,value为字典所有键对应的初始值,默认为None

3.批量添加

dict1.update(dict0)#把字典dict0的键/值对更新到dict1里

6.2.删除88

del dict0[‘key’]#根据键删除对
value=dict0.pop(key)#删除字典给定键 key 所对应的对,返回值为被删除的值。
item=dict0.popitem()#删除字典中的最后一对键和值并返回该对(括号内无参数)。

6.3.遍历

for key,values in dict0.items(): 
for key in dict0.keys():
key in dict0.keys()#如果键在字典dict0里返回true,否则返回false
for value in dict0.values():
value in dict.values()#如果值在字典dic0t里返回true,否则返回false

6.4.求逆**

d0={'a': 1, 'c': 3, 'b': 2}
d1=dict([k, v] for k, v in d0.items())#{'a': 1, 'c': 3, 'b': 2}

6.5.类型转换

dict0={'Name': 'Runoob', 'Age': 7, 'Class': 'First'}
print(type(dict0))#返回输入的变量类型<class 'dict'>
print(str(dict0))#输出字典,以可打印的字符串表示。{'Name': 'Runoob', 'Age': 7, 'Class': 'First'} 	

7.集合

7.1.添加元素**

s= set()
s.add('element')#添加单个元素,{'element'}
s.update({1,2},[3,4],{5:6},"7")#添加列表,元组,字典,多个则用逗号分开,{'element',1,2,3,4,5}

7.2.移除元素**

s.discard( x )#移除集合中的元素,且如果元素不存在,不会发生错误。
s.pop()#集合进行无序的排列,然后将这个无序排列集合的左面第一个元素进行删除。

7.3.基本操作**

1.赋值

a={'a','b','r','a'}
#或者
a = set('abra')#{'a', 'r', 'b'}自动去重
b = set('al')#{'a','l'}

2.运算

element in basket # 快速判断元素element是否在集合basket内                         
a - b#{'r', 'b'}集合a中包含而集合b中不包含的元素                        
a | b#{'a', 'r', 'b', 'l'}    并               
a & b# {'a'}    交           
a ^ b#{'r', 'b', 'l'} 补

3.类似列表推导式,同样集合支持集合推导式(Set comprehension)

a = {x for x in 'abracadabra' if x not in 'abc'}#{'r', 'd'}

8.相同点

8.1.清空复制

clear() copy()#列表字典集合都有清空复制操作,元组和字符串没有

8.2.最大最小值

max(),min()#字符串列表元组

8.3.len(),enumerate(字典中是键和下标)五者全有

enumerate(sequence, [start=0])#用于将一个可遍历的数据对象组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中
#sequence:一个序列、迭代器或其他支持迭代对象。
#start:下标起始位置。
index=[i for i,x in enumerate(a) if x == 1 ]

9.end 关键字

print(1,end=',')#用于将结果输出到同一行,或者在输出的末尾添加不同的字符
print(2,end=',')
#1,2,

10.循环

1

for i in range(-10, -100, -30) :#不包含100 
	print(i)
#-10 -40 -70

2

count = 0 
while count < 3: 
	print (count, " 小于 3") 
	count = count + 1 
else: 
	print (count, " 大于或等于 3")
#0  小于 3
#1  小于 3
#2  小于 3
#3  大于或等于 3

11.迭代器和生成器

11.1.创建迭代器对象的两种方法

1.直接创建

it=iter(seq)#seq可以是五者,字典的话针对键
it = iter([1,2,3,4])    	 # 创建迭代器对象
print (next(it))#1   # 输出迭代器的下一个元素
print (next(it))#2

2.函数中的yield

def func(max):
	i=1
    while i<max:
        i=i+1   
        yield i  
it=func(5)

11.2.调用迭代器

1.循环遍历

for x in it:
    print (x, end=" ")
#1 2 3 4
while True:
    try:
        print (next(it))
    except:
        break

2.直接读取

x1,x2,x3,x4=it
print(x1,x2,x3,x4)

12.函数

12.1.形参后加(:数据类型)指定形参数据类型

12.2.可更改和不可更改对象

strings, tuples, 和 numbers 是不可更改的对象,而 list,dict 等则是可以修改的对象。
函数内直接对传入的列表修改会导致函数外该列表改变,最好在函数内另外创建别的列表进行存储,因为传入的是实参的引用。而strings等不会改变。

import  copy
x=[1,[2,[3]]]
y=x
z=copy.copy(x)#等价于z=x.copy()
w=copy.deepcopy(x)
x[0]=3
print(x,y,z,w)#[3, [2, [3]]] [3, [2, [3]]] [1, [2, [3]]] [1, [2, [3]]]
x[1][0]=4
print(x,y,z,w)#[3, [4, [3]]] [3, [4, [3]]] [1, [4, [3]]] [1, [2, [3]]]
x[1][1][0]=4
print(x,y,z,w)#[3, [4, [4]]] [3, [4, [4]]] [1, [4, [4]]] [1, [2, [3]]]

12.3.*

1. ∗ * 的作用

#将列表、元组、字典(的键)、集合、numpy中元素都拆成一个一个的独立元素
List = ['a', 2, 3]#*List:a 2 3
Tuple = ('b', 'c', 5)#*Tuple :b c 5
Dict = {'name': 'Ada', 'age': 23}#*Dict:name age
ndarray = np.array([2, 3, 4])#*ndarray:2 3 4

2. ∗ * args形参的使用

def fun(*args):#当传入多个位置参数,这多个位置参数会自动组成一个元组
    print(args)
fun(2, 'alex', [3])#(2, 'alex', [3]) 

3. ∗ ∗ ** kwargs形参的使用

def fun(**kwargs):#当传入多个关键字参数,这多个位置参数会自动组成一个字典
    print(kwargs)  
fun(name='Alvin', age=23, things=[1, 2, 'a'])#{'name': 'Alvin', 'age': 23, 'things': [1, 2, 'a']}

13.输入和输出

1.标准化输出

print('常量pi的值近似为 {:.3f},e的值为:{:.3f}。'.format(math.pi,math.e))#冒号后.3表示保留三位小数,冒号后b 二进制d十进制o八进制x十六进制
#旧版 
print('常量pi的值近似为:%5.3f,e的值为:%5.3f。' % (math.pi,math.e))

2.键盘输入

str = input("请输入:");#输入内容自动转换为字符串
print ("你输入的内容是: ", str)
#请输入:菜鸟教程
#你输入的内容是:  菜鸟教程

14.import os

1.按固定顺序读取文件夹中所有图片名字,带后缀

data  =os.listdir(dirc)#dirc为图片所在文件夹路径  

2.重命名

os.rename(old,new)

3.获取目录

print(os.getcwd())#获取当前目录
print(os.path.abspath(os.path.join(os.getcwd(), "..")))#获取上级目录
print(os.path.abspath(os.path.join(os.getcwd(), "../..")))#获取上上级目录
print(os.path.abspath(os.path.join(os.getcwd(), "../../..")))#获取上上上级目录

4.对路径分片操作

import os
dir='/Users/yang/Desktop/test2.py'
print(os.path.splitext(dir))#('/Users/yang/Desktop/test2', '.py')
print(os.path.split(dir))#('/Users/yang/Desktop', 'test2.py')
print(os.path.basename(dir))#test2.py

5.遍历
在这里插入图片描述

for root, dirs, files in os.walk(dir):
        # root 表示当前正在访问的文件夹路径,root对dir由深度到广度进行遍历,即先dir,在遍历dir中文件夹,再对dir中文件夹里的文件夹遍历。
        # dirs 表示该路径下的文件夹名folder	
        # files表示该路径下的文件名file

6.判断路径是否存在

os.path.exists(path)

6.创建一个路径

os.makedirs(path)

7.清空路径内所有文件

def clear_images(path):#
    names=os.listdir(path)
    for name in names:
        os.remove(os.path.join(path,name))

8.添加环境路径

15.命名

1.global函数内部修改全局变量,只要是全局变量只能global

num = 1
def fun1():
    global num  # 需要使用 global 关键字声明
    print(num) #1
    num = 123
    print(num)#123
fun1()
print(num)#123

2.nonlocal修改嵌套作用域(enclosing 作用域,外层非全局作用域)中的变量

def outer():
    num = 10
    def inner():
        nonlocal num   # nonlocal关键字声明
        num = 100
        print(num)#100
    inner()
    print(num)#100

16.面向对象

16.1.模块

1.if name == ‘main’:的运行原理

if __name__ == '__main__':
   print('程序自身在运行')
else:
   print('我来自另一模块')

2.dir() 函数

dir(‘模块名’) #可以找到模块内定义的所有名称。以一个字符串列表的形式返回。如果()内无参数则罗列当前程序所有模块名。

3.__ init__.py模块
如果文件夹中包含了 __ init__.py 时,当用 import 导入该文件夹时,会自动执行 init.py 里面的代码

4.标准模块和包暂时用不到

16.2.属性

1.实例属性和类属性

#实例属性每个实例各自拥有,互相独立,而类属性有且只有一份。
class Circle:
   pi = 3.14  # 类属性
   def __init__(self, r):
       self.r = r#实例属性
C=Circle(1)
C.pi=3 #给circle1创建一个与类属性同名的实例属性,优先级比类属性高
print(Circle.pi,C.pi)#3.14,3
del C.pi
print(Circle.pi,C.pi)#3.14,3.14
class father:
    pi=3.14
    def __init__(self):
        self.a=self.pi
f1=father()
print(f1.a,father.pi)#3.14 3.14
father.pi=4
f2=father()
print(f1.a,father.pi,f2.a)#3.14,4,4

2.类方法必须包含self
3.私有属性
类属性前加两个下划线,声明该属性为私有,不能在类的外部被使用或直接访问。
4.私有方法
类方法(函数)前加两个下划线声明该方法为私有方法,只能在类的内部调用 ,不能在类的外部调用。
5.类外可以直接创建实例属性

16.3.继承

1.调用顺序
继承多个父类class son(father1, father2, father3…):
father1,father2中有相同方法时调用最前面的father1
2.子类不重写__init__()方法

#子类不重写__init__()方法,实例化子类后,会自动调用父类的__init__()的方法。
#子类重写__init__()方法,实例化子类后,将不会自动调用父类的__init__()的方法。
class father:
    def __init__(self,a):
        self.a=a
class son(father):
    def p(self):
        print('父类self.a:',self.a)
s=son(1)
s.p()

3.子类重写__init__()方法又需要调用父类的__init__()方法

#使用super关键词:
class father:
    def __init__(self,f):
        self.f=f
class son(father):
    def __init__(self,s,f):
        super(son,self).__init__(f)#括号内填写父类参数列表
        print('父类self.f:',self.f)#父类self.f: father
        self.s=s
        print('子类self.s:',self.s)#子类self.s: son
son('son','father')

4.子类重写父类其他方法

Son =son() # 子类实例 
Son.Method() #调用子类时先调用子类方法,没有该方法才会在父类找
super(son,Son).Method() #用子类对象调用父类已被覆盖的方法

16.4.方法

1.类方法
不用通过实例化类就能访问的方法。
@classmethod装饰
@classmethod装饰的方法不能使用实例属性,只能是类属性。它主要使用在和类进行交互,但不和其实例进行交互的函数方法上。

class Circle:
   pi = 3.14
   @classmethod#该符号后面只有一个函数是类方法
   def give(cls,x):#cls后也可以传入参数,在调用时输入相应值,通过这个重构类属性
        cls.pi=x
print(Circle().pi)#3.14
Circle.give(1)
print(Circle().pi)#1

@staticmethod装饰
@staticmethod 和@classmethod非常的相似,但是@staticmethod不强制要求传递参数(它做的事与类方法或实例方法一样)。@staticmethod使用在有些和类相关函数,但不使用该类或者该类的实例。使用如更改环境变量、修改其他类的属性等。@staticmethod 修饰的方法是放在类外的函数,我们为了方便将他移动到了类里面,它对类的运行无影响。

class Circle:
    __pi = 3.14
    @staticmethod
    def f(arg1, arg2, ...):

@property装饰
将类方法转换为只读的类属性

class Circle:
    __pi = 3.14
    @property
    def pi(self):
        return self.__pi
print(Circle().pi)#3.14

2.构造方法
__new__概念:
先调用__new__创建实例,它只取下 cls 参数,并把其他参数传给__init__,当这个对象的生命周期结束的时候,__ del__ 会被调用。
__new__在__init__之前被调用:

class Animal:
    def __new__(cls, *args, **kargs):
        print("do __new__")
        return object.__new__(cls, *args, **kargs) # 不返回实例则不会调用__init__
    def __init__(self):
        print("do __init__")
animal = Animal()
#do __new__
#do __init__

重写int类:

class PositiveInteger(int):#继承int类
    def __new__(cls, value):
        return super(PositiveInteger, cls).__new__(cls, abs(value))#返回int类的实例
    def __init__(self,value):
        self.value = value
i = PositiveInteger(-3.2)
print(i)#-3.2
print(i.value)#3

单例:
__new__的返回值(实例)将传递给__init__方法的第一个参数,然后__init__给这个实例设置一些参数,可以return父类__new__出来的实例,或是object的__new__出来的实例。

class Singleton:
    __instance = None
    def __new__(cls, age, name):
        print(cls.__instance)
#None
#<__main__.Singleton object at 0x7f9fb7693e10>
#如果__instance没有或者没有赋值,那么就创建一个对象,并且赋值为这个对象的引用
#再次调用这个方法时返回之前已经创建过的对象,这样就保证了只有1个对象
        if not cls.__instance:
            cls.__instance = object.__new__(cls)
        return cls.__instance
    def __init__(self,age,name):
        self.age = age
        self.name =name
a = Singleton(18, "xxx")
b = Singleton(8, "xxx")
print(id(a))#140323953655312
print(id(b))#140323953655312
print(a.age)#获取a指向的对象的age属性,8
print(b.age)#获取b指向的对象的age属性,8

删除:

def __del__(self):#执行del删除类实例名、类实例属性、类属性时自动执行该语句

3.类的表示
str:

def __str__(self):
	return#必须字符串格式
	#当使用print输出对象的时候,只要自己定义了__str__(self)方法,那么就会打印从在这个方法中return的字符串。

repr:

def __repr__(self):
	return #必须字符串格式
 #和str作用一样,适用于终端或者流输出<<<实例名

format:

class people:
    def __init__(self,name,age):
        self.name,self.age=name,age
    def __format__(self,specification):
        if specification=="":
            return str(self)
        return specification.replace("%s",self.name).replace("%r",self.age)
        
peopleobj=people('zhangsan','31')
print("{}".format(peopleobj))#<__main__.formattest object at 0x000001D013F8F248>
print("{0:%s-%r}".format(peopleobj))#zhangsan-31

class hand:
    def __init__(self,*people):
        self.peoples=list(people)
    def __format__(self,specification):
        if specification=="":
            return str(self)
        return ",".join("{:{fs}}".format(c,fs=specification) for c in self.peoples)

handobj=hand(people("zhangsan","18"),people("lisi","28"))
print("{}".format(people))#<class '__main__.people'>
print("{0:%s-%r}".format(handobj))#zhangsan-18,lisi-28

其他:

def __unicode__(self):
def __hash__(self):
def __nonzero__(self):
def __dir__(self):

4.访问控制(属性的添加与删除)
__ setattr__(self, key, value)
可以用于真正意义上的封装。它允许你自定义某个属性的赋值行为,不管这个属性存在与否,也就是说你可以对任意属性的任何变化都定义自己的规则。
__ getattribute__(self, item)
__ getattribute__看起来和上面那些方法很合得来,但是最好不要使用它。__ getattribute__ 只能用于新式类。在最新版的Python中所有的类都是新式类,在老版Python中你可以通过继承object来创建新式类。__ getattribute__允许你自定义属性被访问时的行为,它也同样可能遇到无限递归问题(通过调用基类的__ getattribute__来避免)。__ getattribute__基本上可以替代__ getattr__。只有当它被实现,并且显式地被调用,或者产生 AttributeError时它才被使用。这个魔法方法可以被使用(毕竟,选择权在你自己),我不推荐你使用它,因为它的使用范围相对有限(通常我们想要在赋值时进行特殊操作,而不是取值时),而且实现这个方法很容易出现Bug。
__ getattr__(self, item):
当用户试图访问一个根本不存在(或者暂时不存在)的属性时,你可以通过这个魔法方法来定义类的行为。这个可以用于捕捉错误的拼写并且给出指引,使用废弃属性时给出警告(如果你愿意,仍然可以计算并且返回该属性),以及灵活地处理AttributeError。只有当试图访问不存在的属性时它才会被调用,所以这不能算是一个真正的封装的办法。
__ delattr__(self, item)
这个魔法方法和 __ setattr__ 几乎相同,只不过它是用于处理删除属性时的行为。

class person:
    def __init__(self,name):
        self.name=name
    def __setattr__(self, key, value):
        print("do __setattr__")
        object.__setattr__(self,key,value)
    def __getattribute__(self, item):
        print("do getattribute")
        return object.__getattribute__(self,item)
    def __getattr__(self, item):
        try:
            print("do getattr")
            return object.__getattribute__(self,item)
        except:
            return "Not find attribute:{}".format(item)
    def __delattr__(self,item):
        print("do delattr")
        object.__delattr__(self,item)
personobj=person("Li")#do __setattr__
print(personobj.name)#do getattribute #Li
print(personobj.age)#do getattribute #do getattr #Not find attribute:age
personobj.age=27#do __setattr__
print(personobj.age)#do getattribute #27
delattr(personobj,"age")#do delattr
print(personobj.age)#do getattribute #do getattr #Not find attribute:age

5.反射(不常用)

6.自定义序列
列表:

#列表
class List:
    def __init__(self, values=None):
        if values is None:
            self.values = []
        else:
            self.values = values
    def __getitem__(self, key):#定义对容器中某一项使用self[key]方式进行读取操作时的行为,可变和不可变容器类型都需要实现的方法
        return self.values[key]#它应该在键的类型错误式产生TypeError异常,同时在没有与键值相匹配的内容时产生 KeyError异常。
        
    def __setitem__(self, key, value):#定义对容器中某一项使用self[key]方式进行赋值操作时的行为。是可变容器类型必须实现的方法
        self.values[key] = value      #同样应该在合适的时候产生KeyError和TypeError异常。
    
    def __len__(self):                #返回容器的长度,可变和不可变类型都需要实现。
        return len(self.values)
    
    def __delitem__(self, key):
        del self.values[key]
        
    def __iter__(self):               #返回一个迭代器
        return iter(self.values)
    
    def __reversed__(self):
        return reversed(self.values)  #返回一个逆序序列的迭代器
    
    def append(self, value):
        self.values.append(value)
    def first(self):
        return self.values[0]
    def last(self):
        return self.values[-1] 
    def front_section(self, n):
        return self.values[:n]
lis= List([1,2,3,4,5,6])
print(lis[0])#1
lis[0]=100#[100,2,3,4,5,6]
print(len(lis))#6
del lis[0]#[2,3,4,5,6]
it=iter(lis)
print(next(it))#2
print(next(it))#3
print(list(reversed(lis)))
lis.append(7)#[2,3,4,5,6,7]
print(lis.first())#2
print(lis.last())#7
print(lis.front_section(3))#[2, 3, 4]

字典:

class A(object):
    a = 0
    b = 1
    def __init__(self):
        self.a = 2
        self.b = 3
obj = A()
print(obj.__dict__)#{'a': 2, 'b': 3}
class Dictionary:
    def __setitem__(self, key, value):
        self.__dict__[key] = value

    def __getitem__(self, key):
        return self.__dict__[key]

    def __delitem__(self, key):
        del self.__dict__[key]
diction = Dictionary()
diction["one"] = 1
diction["two"] = 2
print(diction['two'])#2
del diction['two']
print(diction['two'])#KeyError: 'two'

容器:

class Contain:
    def __init__(self, data):
        self.data = data
        
    def __contains__(self, x):
        return x in self.data
contain = Contain([2,3,4,5])
#当我们调用if 2 in contain时会调用__contains__这个特殊方法,通过方法中的语句返回一个布尔型的值。
if 2 in contain:
    print("2在contain中")#2在contain中
if 6 not in contain:
    print("6不在contain中")#6不在contain中

7.抽象基类
作为继承的一种,抽象基类有用继承的优点,但是它与普通的继承也有不同之处:
抽象基类不能实例化
子类需要实现基类指定的抽象方法
不妨来试想一个场景:当你开发一个项目或者服务,你需要给上下游的组件提供接口,让别人来调用你的程序接口(Application Programming Interface,API),上下游组件该怎么样才能达到想要的目的和你的组件无缝衔接?需要通过按照你接口中规定的抽象方法来实现,例如,你提供一个访问网络请求的接口,你不会去实现host、username、password的注册和发送请求,这些需要调用的用户去实现,你只需要规定:“调用者必须实现指定方法才能实现调用”即可。

from abc import ABC
from abc import abstractmethod


class Database(ABC):
    def register(self, host, user, password):
        print("Host : {}".format(host))
        print("User : {}".format(user))
        print("Password : {}".format(password))
        print("Register Success!")

    @abstractmethod
    def query(self, *args):
        """
        传入查询数据的SQL语句并执行
        """

    @staticmethod
    @abstractmethod
    def execute(sql_string):
        """
        执行SQL语句
        """
class Component1(Database):
    def __init__(self, host, user, password):
        self.register(host, user, password)

    @staticmethod
    def execute(sql_string):
        print(sql_string)

    def query(self, *args):
        sql_string = "SELECT ID FROM db_name"
        self.execute(sql_string)


class Component2(Database):
    def __init__(self, host, user, password):
        self.register(host, user, password)

    @staticmethod
    def execute(sql_string):
        print(sql_string)

    def query(self, *args):
        sql_string = "SELECT NAME FROM db_name"
        self.execute(sql_string)

comp1 = Component1("00.00.00.00", "abc", "000000")#Host : 00.00.00.00#User : abc#Password : 000000#Register Success!
comp2 = Component2("11.11.11.11", "ABC", "111111")#Host : 11.11.11.11#User : ABC#Password : 111111#Register Success!
comp1.query()#SELECT ID FROM db_name
comp2.query()#SELECT NAME FROM db_name

8.函数调用
当我们给类添加特殊方法__call__后,我们使用实例名进行调用时,它会首先进入__call__方法,执行__call__中的程序。
nn.Module 是所有神经网络单元(neural network modules)的基类,pytorch在nn.Module中,实现了__call__方法,而在__call__方法中调用了forward函数。

class A:
    def __init__(self, age):
        self.age = age
        print('调用__init__')
    def __call__(self, added_age):
        print('调用__call__')
        res = self.forward(added_age)
        return res
    def forward(self, input_):
        print('调用forward')
        return input_ + self.age
a = A(10)#调用__init__
input_param = a(2)#调用__call__#调用forward
print("我现在的年龄是:", input_param)#我现在的年龄是: 12

9.上下文管理器(实现with的类特殊方法)
enter 初始化后返回实例。exit 退出时做处理,如清内存,关闭文件,删除冗余等
程序先进去init方法进行初始化,然后自动进入enter特殊方法,然后通过fr.read调用read()方法,最后退出时自动调用exit方法。

class FileReader:
    def __init__(self):
        print("in init method")
    def __enter__(self):
        print("in enter method")
        return self
    def read(self):
        print("in read method")#with语句调用
    def __exit__(self, exc_type, exc_value,exc_tb):
        print("in exit method")
        del self
with FileReader() as fr:
    fr.read()
    #in init method 
    #in enter method
    #in read method
    #in exit method

10.创建描述符对象

class descriptor:
    def __get__(self, instance, owner):
        print("do get")
        print(instance)
        print(owner)
        return "desc"
    def __set__(self, instance, value):
        print("do set")
        print(instance)
        print(value)
    def __delete__(self, instance):
        print("do del")
        print(instance)
class A:
    a=descriptor()
print(A().a)#do get #<__main__.A object at 0x000002782377F248> #<class '__main__.A'> #desc
A().a=5#do set #<__main__.A object at 0x000001D8E72DF248> #5
del A().a#do del #<__main__.A object at 0x0000027E472BF288>
A.a=5#直接修改类A的类变量,也就是a不再由descriptor描述器进行代理

11.拷贝

import copy

class Mobile:
    def __init__(self,cpu,screen):
        self.cpu=cpu
        self.screen=screen
class Cpu:
    def caculate(self):
        print("cpu执行计算程序")
class Screen:
    def show(self):
        print("屏幕显示")
        
c1=Cpu()
c2=c1

#变量赋值
print(c1)#<__main__.Cpu object at 0x0000022F8B90F548>
print(c2)#<__main__.Cpu object at 0x0000022F8B90F548>

#浅拷贝
s1=Screen()
m1=Mobile(c1,s1)
m2=copy.copy(m1)
print(m1)#<__main__.Mobile object at 0x00000168B33FF808>
print(m2)#<__main__.Mobile object at 0x00000168B33FFF08>
print(m1.cpu)#<__main__.Cpu object at 0x00000168B33FF6C8>
print(m2.cpu)#<__main__.Cpu object at 0x00000168B33FF6C8>

#深拷贝
m3=copy.deepcopy(m1)
print(m1)#<__main__.Mobile object at 0x0000027CEBC4F908>
print(m3)#<__main__.Mobile object at 0x0000027CEBC4F8C8>
print(m1.cpu)#<__main__.Cpu object at 0x0000027CEBC4F7C8>
print(m3.cpu)#<__main__.Cpu object at 0x0000027CEBC52048>

12.pickle
存:

import pickle 
data = {'foo': [1,2,3], 'bar': ('Hello', 'world!'), 'baz': True} 
jar = open('data.pkl', 'wb') 
pickle.dump(data, jar)#将pickle后的数据写入jar文件
jar.close()

取:

import pickle 
pkl_file = open('data.pkl', 'rb')# 与pickle后的数据连接
data = pickle.load(pkl_file)#把它载入进一个变量
print(data)
pkl_file.close()

把一个类保存起来,后续读取它直接使用:

import pickle
class person:
    def __init__(self):
        self.name="cai"
personobj=person()
with open("person.txt",'wb') as f:
    #序列化后存储
    pickle.dump(personobj,f)
with open("person.txt",'rb') as f:
    #逆序列化
    p=pickle.load(f)
    print(p.name)#cai

pickle对象:

import pickle
class person:
    def __init__(self,name):
        print("do __init__")
        self.name=name
    def __getnewargs__(self):
        print("do __getnewnewargs__")
        return "wang",
    def __getstate__(self):
        print("do __getstate__")
        return {"name":"xiao"}
    def __setstate__(self,state):
        print("do __setstate__")
        print(state)
        self.__dict__=state
personobj=person("cai")#do __init__
with open("person.txt",'wb') as f:
     #序列化后存储
     pickle.dump(personobj,f)#do __getnewnewargs__ #do __getstate__
with open("person.txt",'rb') as f:
    #逆序列化
    p=pickle.load(f)#do __setstate__ #{'name': 'xiao'}
    print(p.name)#xiao

13.算术运算
在这里插入图片描述
14.比较运算
在这里插入图片描述
15.其他运算
在这里插入图片描述

17.常用功能

1.random
在这里插入图片描述
2.计时

import time
start = time.perf_counter() 
end = time.perf_counter() 

3.id函数
id#访问变量object的地址

18.读写文件

在这里插入图片描述

1.打开

seq = ["菜鸟教程 1\n", "菜鸟教程 2"]
打开文件的两种方式
f=open("/tmp/foo.txt", "w",encoding='utf-8') 
with open("/tmp/foo.txt", "w",encoding=	'utf-8')as f:#打开文件
f=open()
#后者的f引用之后会自动执行f.close(),即f失效不可再引用

2.读

string=f.read(size)#size表示读取的字符数,不设默认读取所有
string=f.readline()#读取一行,不显示换行符\n
string=f.readlines()#读取所有行,显示换行符\n,每行为一个字符串存入列表

3.写

f.write("Python 是一种非常好的语言。\n我喜欢Python!!\n")
f.writelines(seq)#seq中每个元素当成一行写入

19.错误和异常

19.1异常捕获

try:
    # 尝试执行的代码
    pass
except 错误类型1:
    # 针对错误类型1,对应的代码处理
    pass
except 错误类型2:
    # 针对错误类型2,对应的代码处理
    pass
except (错误类型3, 错误类型4):
    # 针对错误类型3 和 4,对应的代码处理
    pass
except Exception as result:
    # 打印错误信息
    print(result)
else:
    # 没有异常才会执行的代码
    pass
finally:
    # 无论是否有异常,都会执行的代码
    print("无论是否有异常,都会执行的代码")
try:
    num = int(input("请输入整数:"))
    result = 8 / num
    print(result)
except ValueError:
    print("请输入正确的整数")
except ZeroDivisionError:
    print("除 0 错误")
except Exception as result:
    print("未知错误 %s" % result)
else:
    print("正常执行")
finally:
    print("执行完成,但是不保证正确")

19.2 异常传递

def demo1():
    return int(input("请输入一个整数:"))


def demo2():
    return demo1()

try:
    print(demo2())
except ValueError:
    print("请输入正确的整数")
except Exception as result:
    print("未知错误 %s" % result)

19.3.主动抛出异常

def input_password():

    # 1. 提示用户输入密码
    pwd = input("请输入密码:")

    # 2. 判断密码长度,如果长度 >= 8,返回用户输入的密码
    if len(pwd) >= 8:
        return pwd

    # 3. 密码长度不够,需要抛出异常
    # 1> 创建异常对象 - 使用异常的错误信息字符串作为参数
    ex = Exception("密码长度不够")

    # 2> 抛出异常对象
    raise ex
    
try:
    user_pwd = input_password()
    print(user_pwd)
except Exception as result:
    print("发现错误:%s" % result)
  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值