python补漏

本文涵盖了Python的基础知识,包括参数类型、操作符、内置函数、字符串、列表、元组、字典、集合、函数、类、异常处理、IO操作等。深入探讨了对象的特性、函数装饰器、闭包、生成器以及模块和包的使用。同时讲解了类的特殊方法如`__init__`、`__call__`,以及异常处理的`try-except-finally`结构。此外,还介绍了反射机制和异常处理,提供了大量实例帮助理解。
摘要由CSDN通过智能技术生成

parameter:形参
argument:实参

python补漏

  1. try-finally语句中,finally中的return优先级高于try中的
  2. 找出程序耗时过程

python -m dis demo.py

  1. python package offline doc

python -m pydoc -p 5200

  1. python环境信息

python -m sysconfig

内置函数

int()
bin()转换成2进制
oct()转换成8进制
hex()转换成16进制
abs(), pow(), float(), sum(), min(), max()_
round()四舍五入

操作符

== 对比的值

is 对比的变量地址

运算次序

括号>函数>算术运算符>关系运算符>逻辑运算符

三元运算符

value1 if condition else value2

长度不得超过一行

对象

对象三要素

id

type

value

对象类型

  • 不可变对象:num,string,tuple,重新赋值会再次分配地址

  • 可变对象:list,dict,set

    list_eg = [[1,2]]
    list_eg = list_eg * 4
    print(list_eg)
    list_eg[2][1] = 128
    print(list_eg)
    
    >
    [[1, 2], [1, 2], [1, 2], [1, 2]]
    [[1, 128], [1, 128], [1, 128], [1, 128]]
    #可变对象改值的时候,对原来的变量地址上的数据改动
    #可变对象复制的时候,复制的是地址,所以只要相同地址的值变了,所有引用该地址的值都会变
    

    为了避免以上问题,谨慎使用可变对象复制

    若要使用列表复制,参考列表-属性-copy操作

字符串

字符串格式

%d10进制数
%s字符串(string)
%x16进制(hex)
%o8进制(oct)
%f浮点数

前缀字符

r或R包含的文本不转义
b或Bbytes类型

字符串格式转换

str转bytesstring.encode()
bytes转strstring.decode()
str转ASCIIord(string)
ASCII转strchr(number)

在这里插入图片描述

字符串运算

str1 + str2连接
str1 * num复制连接
max(str), min(str)ASCII最大/ 最小
len(str)长度

常用字符串属性

str.capitalize()首字母大写,其余小写
str.counter(char)substr字符个数
str.format()格式化输出
str.lower()变成小写
str.upper()变成大写
str.strip()删除两边所有空
str.split(char)以char分割
str.title()str的所有字母都大写
str.center(num,char)在str两边各填充num/2个char
str.ljust(num,char)在str右边填充num个char
str.rjust(num,char)在str左边填充num个char
'test'.center(50,'-')
>'-----------------------test-----------------------'
'test'.ljust(50,'-')
>'test----------------------------------------------'
'test'.rjust(50,'-')
>'----------------------------------------------test'

列表

属性

list.append()追加
list.insert(index,item)指定位置插入
list.remove(item)删除指定值
list.index(item)返回item的索引
list.count(item)返回item个数
list.clear()清空
list.reverse()逆序
list.sort(reverse)reverse:bool类型,默认False,True降序,False升序
list.copy()复制列表,重新分配地址赋值

列表解析

#简单
[i**2 for i in range(10)]
>[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
#复合
[i**2 for i in range(10) if i % 2 ==0]
>[0, 4, 16, 36, 64]
#复合
[x * y * z for x in [2,3] for y in [5,7] for z in [11,13]]
>[110, 130, 154, 182, 165, 195, 231, 273]

元组

注意

(1,)是元组

(1)是数字

类型转换

# 集合转换元组
sets = {1,'name',(1,2,3)}
tuple(sets)

>(1, 'name', (1, 2, 3))
# 字典转元组
dic = {'name':'charls','age':20}
tuple(dic)

>('name', 'age')
#只记录keys的值

集合

集合性质

无序,唯一

用{}包括,但不能用{}初始化,要使用set()初始化

集合操作

交集set1 & set2 或 set1.intersection(set2)
并集set1 | set2 或 set1.union(set2)
是否有交集set1.isdisjoint(set2)
差集set1-set2 或 set1.difference(set2)
是否子集set1 < set2 或 set1.issubset(set2)
是否父集(超集)set2 > set1 或 set2.issuperset(set1)
对称差集(不同元素集合)set1 ^ set2 或 set1.sysmmetric_difference(set2)
set.add(item)增加单个元素
set.update(item1,item2,item3…)增加多个元素
set.remove(item)_
set.pop()随机删除一个
set.clear()_

可迭代对象传入集合的时候,可迭代对象会被拆开

集合运算

  • 两集合的对称差集交集并集=两集合的并集
  • 两集合的并集交集差集=两集合的对称差集

字典

性质

  • 键唯一,值不唯一
  • 键必须是不可变类型(字符串,数字,元组),值可以是任何类型(数字,函数,类,各种结构都行)
def func1():
    print(123)
def func2():
    print(456)

a = {1:func1,2:func2}
print(a[1]())

>123
 None
#func1输出123,返回None

查,删

dict1[key] # key不存在,会抛出异常

dict1.get(key) # key不存在,会返回None

del dict1[key] # 删除键值对

dict1.pop(key) # 删除键值对,返回删除值

属性

dict.values()_
dict.keys()_
dict.items()_
dict1.update(dict2),dict.copy()结果一样
dict.clear()_

字典解析

a = {1:1,2:2,3:3,4:4}
b = {key:value for key,value in a.items() if value % 2 == 0}
b
>{2: 2, 4: 4}

函数

关键字传参

在函数传参的过程中,如果某一个位置以关键字传参,那么后面的位置只能以关键字传参。

def func(a,b,c):
    pass
func(1,c=2,3)
func(1,b=2,3)
#都是错的

默认参数

默认参数只能位于所有未指定形参的后面

def func(a=1,b,c):
    pass
func(1,2)
func(b=2,c=3)
#都是错的

不定长参数

  • 元组型形参*args将所有传过来的值当作一个元组来处理

  • 字典型形参**kwargs将所有传过来的值当作一个字典来处理

  • 元组型形参位于一般参数后面,字典型形参位于元组型形参后面

def func(name,age,career,*args,**kwargs):
    pass
func(item1,item2,item3,item4,item5,dict1,dict2,dict3)
#name=item1,age=item2,carre=item3
#args=(item4,item5)
#kwargs={dict1,dict2,dict3}

局部变量和全局变量

  • 函数内部无法引用,修改全局变量
  • 加上global之后才能引用,修改
a = 1
def func():
    a += 1
func()
a
#错误
a = 1
def func():
    global a
    a += 1
func()
a

>2
函数里的函数

函数里的内部函数只能引用外部函数的变量,但是不能修改

def func():
    a = 1
    def func1():
        print(a)
    func1()
func()

>1

内部函数要想修改外部函数的变量,只能加nonlocal。内部函数可以引用全局变量,但无法修改全局变量

def func():
    a = 1
    def func1():
        nonlocal a
        a += 1
    func1()
    print(a)
func()

>2

闭包

  • 存在函数嵌套
  • 内部函数引用外部函数的变量
  • 内部函数不能引用全局变量
  • 外部函数的返回值必须是内部函数的函数名
def outer_func():
    out = 123
    def inner_func():
        print(out)
    return inner_func
def outer(num1,num2):
    num = num1 + num2
    def inner():
        inner_str = '{}+{}={}'.format(num1,num2,num)
    	return inner_str
	return inner

test = outer(1,2)
print(test())

>1+2=3
闭包特有属性

闭包都有__closure__属性,该属性返回外部函数的变量内存地址,类型为元组

如果不是闭包,则返回None

通过打印.__closure__[index].cell_contents来获取外部函数变量的值

print(test.__closure__)
print(test.__closure__[0].cell_contents)
print(test.__closure__[1].cell_contents)
print(test.__closure__[2].cell_contents)

>(<cell at 0x00000278E01E4B80: int object at 0x00007FF86A9D2760>, <cell at 0x00000278E01E4B20: int object at 0x00007FF86A9D2720>, <cell at 0x00000278E01E49D0: int object at 0x00007FF86A9D2740>)
3
1
2

return

无return的时候,默认返回None

高阶函数

函数1的函数名作为参数传递给函数2函数2返回函数1的函数名

import time

def get_info():
    information = 'Entered show_infor'
    return information

def execution(func):
    start = time.time()
    for i in range(1000000):
        info = func()
    end = time.time()
    print(info)
    print('Cost {:.2f}s'.format(end-start))

execution(get_info)

>Entered show_infor
 Cost 0.09s
#重构execution
def execution(func):
    start = time.time()
    for i in range(1000000):
        info = func()
    end = time.time()
    print(info)
    print('Cost {:.2f}s'.format(end-start))
    return func

#返回函数名
info = execution(get_info)
#执行函数
info()

>Entered show_infor
 Cost 0.08s
 'Entered show_infor'

函数装饰器@

用于装饰函数,为函数增加附加功能

1.被装饰函数无参无返回
import time

def timer(func):
    def execution():
        start = time.time()
        func()
    	end = time.time()
        print('Cost {:.2f}s'.format(end-start))
    return (execution)

@timer
def info():
    information = 'Entered info'
    print(information)
    
info()

>Entered info
 Cost 0.00s

# 1.timer(info)
# 2.返回了execution,先执行execution(),execution()可以访问外部函数的func
# 3.先访问func,后输出cost
2.被装饰函数有参有返回
import time

def timer(func):
    def execution(*args,**kwargs):
        start = time.time()
        ret = func(*args,**kwargs)
        end = time.time()
        print('Cost:{:.2f}'.format(end-start))
        return ret
    return execution

@timer
def info(name,age):
    info_str = "my name is {} and i'm {} years old".format(name,age)
    print(info_str)
    return ('info函数返回')

info('Charles',20)

>my name is Charles and i'm 20 years old
 Cost:0.00
print(info('Charles',20))
> my name is Charles and i'm 20 years old
  Cost:0.00
  info函数返回
# 和1一样,最后print输出了info的返回值
3. 装饰器和被装饰函数都有参
def decorator(*dargs,**dkwargs):
    def middle(func):
        def inner(*args,**kwargs):
            print('装饰器参数',dargs,dwargs)
            print('函数参数',args,kwargs)
            return func(*args,**kwargs)# func被调用了
        return inner
    return middle
# 一步步调用内部函数
@decorator()
def test1(name,age):
    info = '{}-{}'.format(name,age)
    return info

@decorator(1,2,city='shenzhen')
def test2():
    print('这是测试2函数体')
    return('这是测试2返回值')

@decorator('python','java',level='preliminary')
def test3(city,province,*args,**kwargs):
    info = '{} in {}'.format(city,province)
    print(info)
    print(args)
    print(kwargs)

test1('charles',20)
>装饰器参数 () {}
 函数参数 ('charles', 20) {}
    
test2()
>装饰器参数 (1, 2) {'city': 'shenzhen'}
 函数参数 () {}
 这是测试2函数体

test3('shenzhen','guangdong','china',year=2100)
>装饰器参数 ('python', 'java') {'level': 'preliminary'}
 函数参数 ('shenzhen', 'guangdong', 'china') {'year': 2100}
 shenzhen in guangdong
 ('china',)
 {'year': 2100}

生成器、迭代

在这里插入图片描述

from collections import Iterable,Iterator

可迭代对象(Iterable)

可以被循环取值的对象

  • 容器:字符串,列表,字典,集合
  • 生成器(generator)以及带有yield的函数
判断
isinstance(obj,Iterable)

迭代器(Iterator)

可以被next()函数调用(具有__next__()方法),可以不断返回下一个值的对象

  • 所有迭代器均为可迭代对象
  • 不是所有可迭代对象都是迭代器
判断
isinstance(obj,Iterator)
读取迭代器内容
  • next()或__next__(),当所有值都读完再运行__next__()会抛出StopIteration异常
  • for 循环

生成器(Generator)

是一种特殊的迭代器

生成器一定是迭代器

类型
  • 生成器表达式(Generator Expression),类似列表生成式,只是将**[]换成了()**
  • 生成器函数(Generator Function),类似函数,但函数体中带有yield。yield相当于普通函数的return,下一次读值将从上一次的yield读取

递归

  • 在函数内部调用函数自身,而且有可以达成的终止条件,不是死循环

  • 理论上,所有递归函数都可以写成循环的方式

  • 递归最大深度是1000,超过递归上限会抛出

    RuntimeError:maximum recursion depth exceeded

模块

要导入包,必须得带有__init__.py文件(现在不确定,我试了一下,不带init文件也能导入)

导入包路径

sys.path查看路径
sys.path.append(path)路径列表追加路径
sys.path.insert(index,path)追加路径时,指定路径列表中搜索优先级
__file__给出当前文件绝对路径(有些编译器是相对路径)
os.path.abspath(__file__)绝对路径
os.path.dirname(__file__)当前文件夹的绝对路径

标准库

内置模块是用C语言写的 python标准库官方docs

私有方法和私有属性

名字前带有__的属性名和方法无法在外部直接访问

class Test():
    def __init__(self,params):
        self.__params = params

test = Test(123)
test.__params

>AttributeError: 'Test' object has no attribute '__params'

访问私有属性

  1. 通过类内方法传值
class Test():
    def __init__(self,params):
        self.__params = params
        
    def get_params(self):
        return self.__params
test = Test(123)
test.get_params()

>123
  1. 通过对象名._类名__私有属性名访问
class Test():
    def __init__(self,params):
        self.__params = params
        
    def get_params(self):
        return self.__params
test = Test(123)
test._Test__params

>123

访问私有方法

通过对象名._类名__私有方法名()访问

class Test():
    def __init__(self,params):
        self.__params = params
        
    def __inner(self):
        print('enter __inner')
test = Test(123)
test._Test__inner()

>enter __inner

继承

TODO:

类的方法

静态方法@staticmethod

使用函数修饰器@staticmethod

这种方法与类无关,虽然在类里,但是无法调用类的属性,而且不用self,相当于把一个函数直接缩进移到类里

调用方式

使用类名调用或者使用实例名调用

class Test():
    def __init__(self):
        pass
    
    @staticmethod
    def func():
        print('123')
        
test = Test()
test.func()
Test.func()

>123
 123

类方法@classmethod

使用函数修饰器@classmethod

只能调用类的属性,无法访问实例化后的属性,也就是无法访问__init__()里面的内容

class Test():
    name = 'Charles'
    age = 20
    def __init__(self,name,age):
        self.name = name
        self.age = age
    
    @classmethod
    def func(self):
        # 类方法的self.arg 实际上访问不到,还是会访问类的arg
        print(self.name)
        print(self.age)
        print(Test.name)

test = Test('Bob',30)
test.func()

>Charles
 20
 Charles

属性方法@property

适用场景:在外部修改类属性的时候,无法同时检查值是否合理,针对改的值做出提醒

使用@property,可以将与属性名相同的方法当作属性来调用,同时添加操作

使用@attr.setter,修改属性attr的时候,调用的是被修饰的函数

@attr.deleter,删除属性attr的时候,调用的是被修饰的函数

class Person():
    
    def __init__(self,name,age):
        self.__name = name
        self.__age = age
    
    @property
    def name(self):
        return self.__name
    
    @property
    def age(self):
        return self.__age
    
    @name.setter
    def name(self,name):
        self.__name = name
    
    @age.setter
    def age(self,age):
        if age < 0 or age > 100:
            raise ValueError('age must in [0,100]')
        else:
            self.__age = age
    
    @name.deleter
    def name(self):
        del self.__name
        
    @age.deleter
    def age(self):
        del self.__age
pe = Person('Charles',100)
pe.name
pe.age

>'Charles'
 100
pe.name = 'Bob'
pe.age = 10
pe.name
pe.age

>'Bob'
 10
pe.name
del pe.name
pe.name

>'Bob'
 AttributeError: 'Person' object has no attribute '_Person__name'
pe.name = 'Sam'
pe.age = -10

>ValueError: age must in [0,100]

使用stu.__dict__可以看到stu只有两个属性,{’_Person__age’: 10, ‘_Person__name’: ‘Bob’},并不是__name和__age

类的特殊成员方法

__doc__

打印描述信息

class Person():
    '''
    一个关于人的类
    '''
    def __init__(self):
        pass

Person.__doc__

>'\n    一个关于人的类\n    '
__module__和__class__

__module__会返回所属模块的模块名

__class__会返回所属类的类名相关信息

./hello.py

class Hello():
    def __init__(self):
        ret = 'hello'

./test.py

from hello import Hello

ret = Hello()

print(Hello.__module__)
print(ret.__module__)
print(Hello.__class__)
print(ret.__class__)

>hello
 hello
 <class 'type'>
 <class 'hello.Hello'>
 # class type是未实例化的类的类型,注意在这里是type类型的意思,不是class类型
__init__

实例化时自动触发

__del__

当对象在内存中释放时,自动触发

__call__

实例化后调用自动触发

class Test():
    def __init__(self):
        print('enter init')
    
    def __call__(self):
        print('enter call')
        
test = Test()
test()
test()

>enter init
 enter call
 enter call
__dict__

类和实例都能调用,会打印类或者实例的所有属性

class Test():
    def __init__(self,name,age):
        self.name = name
        self.age = age
        
test = Test('charles',20)
Test.__dict__
test.__dict__

>mappingproxy({'__module__': '__main__',
              '__init__': <function __main__.Test.__init__(self, name, age)>,
              '__dict__': <attribute '__dict__' of 'Test' objects>,
              '__weakref__': <attribute '__weakref__' of 'Test' objects>,
              '__doc__': None})

{'name': 'charles', 'age': 20}
__str__

在打印的时候自动调用

class Test():
    def __init__(self):
        pass
    
    def __str__(self):
        ret = 'enter str'
        return ret
    
test = Test()
print(test)
print(Test())

>enter str
 enter str
__getitem__,__setitem__,__delitem__

__getitem__一般用来获取数据,__setitem__一般用来改变数据,__delitem__一般用来删除数据,删除后的序列数据顺位向前移动

如果将着三种方法重构一下,将这三种方法的功能互换一下,也能运行,但是强烈不建议这样做

class Test():
    def __init__(self):
        self.data = list(range(100))
    
    def __getitem__(self,index):
        print('进入getitem')
        return (self.data[index])
        
    def __setitem__(self,index,value):
        print('进入setitem')
        self.data[index] = value
    
    def __delitem__(self,index):
        print('进入delitem')
        del self.data[index]
        
>进入getitem
 15
 进入setitem
 100
 进入delitem
 进入getitem
 IndexError: list index out of range
类生成过程

__new__ -> __init__ ->__call__

反射

getattr

getatrr(name,attr/method(),default)

相比于直接使用name[attr]的方法,可以判断有没有方法,而且即使属性或者方法不存在也不会报错,而是会返回默认值(如果不指定默认值,属性或者方法不存在时会报错)

a = {'name':123,'age':456}
getattr(a,'dsd',[147,258])

a['dsd']
>[147, 258]

hasattr

hasattr(实例名,属性/方法())

返回True/False

setattr

在添加属性时,功能和name[attr]=value重复

在类中添加其他类的方法

class Cat():
    def __init__(self):
        pass
    
    def sleep(self):
        print('sleeping')
    
    def wake(self):
        print('waking')
        
class Dog():
    def __init__(self):
        pass
cat = Cat()
dog = Dog()
setattr(dog,'sleep',cat.sleep)
setattr(dog,'wake',cat.wake)
dog.sleep()
dog.wake()

>sleeping
 waking

delattr

delattr(实例名,属性名)

异常处理

try:
    pass
except <code>:
    pass
else:
    pass
finally:
    pass

执行逻辑:先执行try下的,有异常跳到except,没异常跳到else。无论有没有异常都会执行finally

  • exceptfinally必须用一个或者都用
  • 所有异常都能用Exception代替
try:
    open('./data.pdf')
except IndexError as e:
    print('frist assert',e)
except Exception as e:
    print('万能异常',e)
else:
    print('不可能进入')
finally:
    print('test完毕')

>万能异常 [Errno 2] No such file or directory: './data.pdf'
 test完毕

常见异常

在这里插入图片描述在这里插入图片描述在这里插入图片描述

触发异常

raise Exception('有异常')

自定义异常

class MyException(Exception): 
    def __init__(self,message):
        self.message = message

try:
    raise MyException("错误原因")
except MyException as e:
    print(e)
    
>错误原因

IO

获取输入

message = input(‘input what you want’)

操作

  • 查看变量所占内存大小

    a.__sizeof__()

  • 查看内建名称空间的内容

    dir(obj):返回参数和方法列表

    dir()
    
    >['In',
     'Out',
     '_',
     '__',
     '___',
     '__builtin__',
     '__builtins__',
     '__doc__',
     '__loader__',
     '__name__',
     '__package__',
     '__spec__',
     '_dh',
     '_i',
     '_i1',
     '_ih',
     '_ii',
     '_iii',
     '_oh',
     'autopep8',
     'exit',
     'get_ipython',
     'json',
     'quit']
    
    dir([])
    
    >['__add__',
     '__class__',
     '__contains__',
     '__delattr__',
     '__delitem__',
     '__dir__',
     '__doc__',
     '__eq__',
     '__format__',
     '__ge__',
     '__getattribute__',
     '__getitem__',
     '__gt__',
     '__hash__',
     '__iadd__',
     '__imul__',
     '__init__',
     '__init_subclass__',
     '__iter__',
     '__le__',
     '__len__',
     '__lt__',
     '__mul__',
     '__ne__',
     '__new__',
     '__reduce__',
     '__reduce_ex__',
     '__repr__',
     '__reversed__',
     '__rmul__',
     '__setattr__',
     '__setitem__',
     '__sizeof__',
     '__str__',
     '__subclasshook__',
     'append',
     'clear',
     'copy',
     'count',
     'extend',
     'index',
     'insert',
     'pop',
     'remove',
     'reverse',
     'sort']
    
    import builtins
    dir(builtins)
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值