Python教程

Python 学习笔记7

本文主要是介绍Python 学习笔记7,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

Python 学习笔记

文件处理

文件的读取与写入

open()函数,用来读取或写入文件,用法为

stream=open('文件路径','操作方式')
可以对这个流进行文件内容的操作

更多操作模式如下


stream.readline()返回的是文件里一行的内容,且在使用后,文件的开始位置会变为下一行的起始位置,当无行可读时,返回None

由于读取的是行,所以会把行末尾的换行符也读入,显示出来便是print出来多了一个空行,但是最后一行没有

stream.read()返回全部内容

stream.readlines()返回每一行的内容形成一个列表并返回

stream.write(str)向文件中写入,写入后指针位置位于字符串尾

stream.write(list)向文件中依次写入list内的内容

文件夹操作

os.remove(path)删除文件

os.rmdir(path)删除文件夹,但文件夹必须为空

os.listdir(path)返回一个由该文件夹内所有文件名组成的列表

os.chdir(path)切换当前目录

os.getcwd(path)返回当前目录

os.splitext(path)将文件路径名和文件的类型分割开来,返回值是一个元组

os.split(path)将文件路径和文件名(含后缀)分割开来,返回值是一个元组

附上手写的文件夹复制代码

import os
def copydir(src,target):
    filelist=os.listdir(src)
    for file in filelist:
        path=os.path.join(src,file)
        if os.path.isdir(path):
            path1=os.path.join(src,file)
            path2=os.path.join(target,file)
            if os.path.isdir(path2):
                pass
            else:
                os.mkdir(path2)
                copydir(path1,path2)
        else:
            with open(path,'rb') as stream:
                container=stream.read()
                path1=os.path.join(target,file)
                with open(path1,'wb') as wstream:
                    wstream.write(container)

异常处理

try...except语句

当try语句内出现异常错误时,except会自动接受异常并执行except内的语句

可以使用多条except语句接受不同的异常类型

注意:except语句按照从上到下顺序接受异常,且只接受一次,所以表示所有异常的Exception类要放在最后

try...except...else语句
当无异常抛出时,便会执行else语句下的内容

try...except...finally语句
无论是否有异常抛出,即使有崩溃产生,finally中的语句一定会执行,如果有返回值则会覆盖掉之前的返回值

raise语句

raise可以抛出一个自定义的异常,类型以及异常的具体内容自己定

使用方法为raise ExceptionName(str)

try:
    a = input("输入一个数:")
    #判断用户输入的是否为数字
    if(not a.isdigit()):
        raise ValueError("a 必须是数字")
except ValueError as e:
    print("引发异常:",repr(e))
# repr() 返回将对象直接转化为的字符串

在没有引发过异常的程序使用无参的 raise 语句时,它默认引发的是 RuntimeError 异常

当之前已经使用过一个raise时,使用无参的 raise 语句默认引发和上一个相同的异常,但有多个的异常时默认引发的还是 RuntimeError 异常

生成器

可以通过类似列表推导式的方法,迭代出一系列的值,同时相对于直接的列表节约了大量空间

格式为

generator=(x for x in range(10))

和列表推导式的唯一区别就是[]变成了()

使用时可以通过generator.__next()__或者next(generator)来迭代出下一个值

当超出迭代器的范围时,再次调用会爆出StopIteration的错误

生成器的另一种方法是利用函数

def gen():
    i = 0
    while i<5:
        temp = yield i
        print(temp)
        i+=1

当函数含有yield关键字时,该函数代表的就是一个生成器,使用方法为f=gen(),对这个f可以使用上述的一系列操作

yield的作用是返回值的同时在此处暂停,同时当下一次调用该生成器时从这个断点继续运行

f.send(obj)send函数的作用可以向生成器内传入一个对象,对于如同temp = yield i的语句作用是将该对象在断点处赋值给temp并且运行下去,所以要注意的是在第一次调用生成器时不能使用send函数,正常使用f.__next__()便相当于是f.send(None)

迭代器

可以被next()函数调用并返回下一个元素的对象都能可以称为迭代器

迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退

可以通过isinstance()函数判断是否是可迭代对象,注意要先from collections import Iterable

但是可迭代的对象不一定是迭代器,可以通过iter()使他变成一个迭代器

面向对象编程

类的创建

创建一个类的格式

class name:
    属性1
    属性2
    函数1:
    函数2:

函数方法

就是写在类里面的函数,可以通过类创建的实例对象调用,注意函数的第一个参数必须是self表示本身这个对象

在python中不支持函数名一样但是参数不相同的函数,后面一个函数会覆盖掉前面一个同名的函数

格式如下

def name(self,*args,*kwargs):
    ...
    ...

类方法,静态方法

类方法与静态方法都可以不依赖于对象使用,直接使用类名.函数的格式调用,同时,操作的对象也只能是类的属性
类方法的格式

def class:
    @classmethod
    def name(cls,*args,**kwargs):
        ...
        ...

类方法的第一个参数必须是cls,表示本类,使用时函数前必须添加@classmethod关键字

静态方法的格式

def class:
    @staticmethod
    def name(*args,*kwargs):
        ...
        ...

注意的是静态方法不需要self或者是cls参数,但是便也不能使用任何的类的属性和对象

魔法方法

可以类比构造函数,析构函数一类的

魔法方法的格式在开头和结尾各有两个下划线不能舍弃,名字均为定义好的

__init(self)__构造函数,创建对象时调用

__new(cls)__构造函数,调用的优先级比init更高,参数是cls,必须有返回值,当返回值是一个当前类的对象时,init也会随后被调用

__new()__也属于类的静态方法

__del()__析构函数

__call()__当使用创建的对象加括号时执行

__str()___返回值是一个字符串,是当采用print()函数时打印出来的字符

__repr()__功能与str类似,同时还是直接使用repr(obj)的返回值,与str的区别是repr(obj)的字符串会带上双引号


关于运算符的魔法方法,类比重载


关系运算 含义
lt 小于
gt 大于
le 小于等于
ge 大于等于
eq 等于
ne 不等于
cmp 用于sort,返回值1,-1,0,比较结果为-1的self放在前面
算数运算 含义
add
sub
mul
truediv
mod 取模
pow 乘方

注意这些用法基本均为__lt(self,obj)__,记得传入另一个比较项的参数名

类属性

类属性所有创建的对象共用,实例化后的对象不可修改,只能通过类名.类属性方式修改,如果有同名实例属性,实例对象会优先访问实例属性。

私有属性和方法

在属性前加上两个下划线便为私有属性,私有属性外界无法直接修改和访问,只能在类的方法内部使用,类比C++中的private关键字和public关键字

property关键字

对于get,set等函数去对于私有属性进行操作显得有些麻烦,为了实现看上去直接对私有属性的操作,可以使用property关键字

class Dog():
    __age=1
    def __init__(self):
        self.__age=1
    @property
    def age(self):
        return self.__age
    @age.setter #名称要和上面一个一样
    def age(self,age):
        self.__age=age
d=Dog()
print(d.age) #直接访问__age私有参数
d.age=2
print(d.age)

要注意的时只有在定义了property函数之后才可以使用setter关键字来指定辅助函数

继承与引用

引用就是在别的类中使用一个已创建的类,正常使用即可,注意传入参数

继承的格式为

class 子类名(父类名):
    def __init__(self):
        super().__init__()

当需要使用到父类的构造函数时,可以使用super()函数来调用父类的构造函数,注意父类的传入参数不能缺少

当子类存在和父类相同函数名的函数时,会对父类的函数进行覆盖,也可以使用super()来调用父类的方法

多继承的语法格式

class 子类名(父类名1,父类名2...)
    pass

如果不同的父类中存在同名的方法,子类对象在调用方法时,会调用最前面的一个父类的方法,实际中应当避免这种情况

python中针对类提供了一个内置属性__mro__可以用来查看方法的搜索顺序。

使用方法

print(C.__mro__)

结果为

(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)

在调用方法时,按照__mro__的输出结果从左至右的顺序查找。

如果再当前类中找到方法,就直接执行,不再向下搜索。

如果没有找到,就顺序查找下一个类中是否有对应的方法,如果找到了最后一个类,依然没有找到方法,程序就会报错。

单例模式

通过某种方法,使得创建的对象共享的是一个地址,使得内存优化。

使用__new__()

class Singleton(object):
    __instance=None
    def __new__(cls):
        if cls.__instance is None:
            cls.__instance = super(Singleton, cls).__new__(cls)
        return cls.__instance
 
obj1 = Singleton()
obj2 = Singleton()

使用装饰器

def singleton(cls):
    instances = {}
    def getinstance(*args,**kwargs):
        if cls not in instances:
            instances[cls] = cls(*args,**kwargs)
        return instances[cls]
    return getinstance

@singleton
class MyClass:
    a = 1

c1 = MyClass()
c2 = MyClass()
print(c1 == c2) 
# 装饰器 singleton返回了一个内部函数 getinstance,该函数会判断某个类是否在字典 instances 中,如果不存在,则会将 cls 作为 key,cls(*args, **kw) 作为 value 存到 instances 中,否则,直接返回 instances[cls]。
这篇关于Python 学习笔记7的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!