ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

python基础-函数、面对对象、文件、异常

2022-07-20 01:31:28  阅读:125  来源: 互联网

标签:__ 文件 函数 python self Base print 父类


一、函数

1.1函数

  python允许我们将常用的代码以固定的格式封装(包装)成一个独立的模块,只要知道这个模块的名字就可以重复使用它,这个模块就叫做函数(Function)。

1.2函数的定义和使用

   

  此格式中,各部分参数的含义如下:

    函数名:其实就是一个符合 Python 语法的标识符,但不建议读者使用 a、b、c 这类简单的标识符作为函数名,函数名最好能够体现出该函数的功能(如上面的 my_len,即表示我们自定义的 len() 函数)。

    形参列表:设置该函数可以接收多少个参数,多个参数之间用逗号( , )分隔。

    [return [返回值] ]:整体作为函数的可选参参数,用于设置该函数的返回值。也可以没有返回值,不写返回值,会有一个默认的返回值None,是否需要根据实际情况而定。return后面所有内容都不执行。

   

  其中,函数名即指的是要调用的函数的名称;形参值指的是当初创建函数时要求传入的各个形参的值。如果该函数有返回值,我们可以通过一个变量来接收该值,当然也可以不接受。

  需要注意的是,创建函数有多少个形参,那么调用时就需要传入多少个值,且顺序必须和创建函数时一致。即便该函数没有参数,函数名后的小括号也不能省略。

二、面对对象

2.1概述

  对于面向过程的思想:需要实现一个功能的时候,看重的是开发的步骡和过程,每一个步蒸都需要自己亲力亲为,需要白己编写代码自己来做。

  对于面向对象的思想:当需要实现一个功能的时候,看重的并不是过程和步骤,而是关心谁帮我做这件事。

  面向对象的三大特征有:封结性,继承性.多志性。

 2.2类、创建对象、属性和方法

  

  1.在类内部获取属性和实例方法,通过self获取;

  2.在类外部获取属性和实例方法,通过对象名获取。

  3.如果一个类有多个对象,每个对象的属性是各自保存的,都有各自独立的地址;

  4.但是实例方法是所有对象共享的,只占用一份内存空间。类会通过self来判断是哪个对象调用了实例方法。

  

   init():实例化的时候需要一些自定义的属性,可以使用init()方法

  

 2.3常用方法

  __str__():将__str__()返回的内容以字符串形式输出 

  __str__()方法触发方式:

    1、使用print()函数触发:触发时,会自动寻找实例对象的方法,若没有则直接按照默认内容输出,有则输出__str__方法的返回值。
    2、使用str()函数触发:如上述代码所示,使用str()触发时,worlds类型是str,是一个字符串,打印输出的是一个字符串words。

   print(zhang) 

2.4 对象的继承

  在程序中,继承描述的是多个类之间的所属关系。

  如果一个类A里面的属性和方法可以复用,则可以通过继承的方式,传递到类B里。那么类A就是基类,也叫做父类;类B就是派生类,也叫做子类。

2.4.1 单继承:子类只继承一个父类

  

  子类在继承的时候,在定义类时,小括号()中为父类的名字。

  父类的属性、方法,会被继承给子类。

 2.4.2 多继承:新建的类可以支持一个或多个父类

   

   

  多继承可以继承多个父类,也继承了所有父类的属性和方法

  当继承了两个或两个以上的类的时候,如果继承的方法或属性有重名,选择继承的第一个。不重名的不受影响。

  子类的魔法属性__mro__决定了属性和方法的查找顺序。

2.4.3子类重写父类属性/方法

  如果子类和父类的方法名和属性名相同,则默认使用子类的。并称为子类重写父类的同名方法和属性。

  

   

2.4.5子类调用父类的同名属性和方法

  当存在继承关系的时候,有时候需要在子类中调用父类的方法,此时最简单的方法是把对象调用转换成类调用,需要注意的是这时self参数需要显式传递。

 

   

  无论何时何地,self都表示是子类的对象。在调用父类方法时,通过传递self参数,来控制方法和属性的访问修改。

  但是这种方式在多层继承中就会有问题(下文super()中会提到),基类Base的构造函数被调用了多次次。这样做还有一些缺点,比如说如果修改了父类名称,那么在子类中会涉及多处修改,在多继承时就需要重复写多次,显得累赘。

2 .4.6 多层继承

  允许多层继承

  

2.4.7 私有权限

  私有权限:在属性名和方法名 前面 加上两个下划线 __

    Python中没有像C++中 public 和 private, protected 这些关键字来区别公有属性和私有属性。Python是以属性命名方式来区分,如果在属性和方法名前面加了2个下划线'__',则表明该属性和方法是私有权限,否则为公有权限。

  类的私有属性 和 私有方法,都不能通过对象直接访问,但是可以在本类内部访问;

  类的私有属性 和 私有方法,都不会被子类继承,子类也无法访问;

  私有属性 和 私有方法 往往用来处理类的内部事情,不通过对象处理,起到安全作用。

2.4.8通过super()来调用父类中的方法

  

  默认情况下,python多继承super()方法只会调用第一个父类的方法(后面多继承需要类名.方法名(self))。

  在super机制里可以保证公共父类仅被执行一次。

  使用3.4.5中的方法,就会出现问题,先看看下面的例子:

class Base(object):
    def __init__(self):
        print("enter Base")
        print("leave Base")
 
 
class A(Base):
    def __init__(self):
        print("enter A")
        Base.__init__(self) #调用父类的构造函数进行初始化
        print("leave A")
 
 
class B(Base):
    def __init__(self):
        print("enter B")
        Base.__init__(self) #调用父类的构造函数进行初始化
        print("leave B")
 
class C(A,B):
    def __init__(self):
        print("enter C")
        A.__init__(self) #调用父类A的构造函数进行初始化
        B.__init__(self) #调用父类B的构造函数进行初始化
        print("leave C")
 
 
c=C()

  运行结果:

enter C
enter A
enter Base
leave Base
leave A
enter B
enter Base
leave Base
leave B
leave C

  从上面的运行结果可以看出,基类Base的构造函数被调用了两次,这是有问题的,正常的应该是:A的构造函数调用一次,B的构造函数调用一次,基类Base的构造函数调用一次。

  接下来使用super()进行调用:

class Base(object):
    def __init__(self):
        print("enter Base")
        print("leave Base")
 
 
class A(Base):
    def __init__(self):
        print("enter A")
        super(A,self).__init__()
        print("leave A")
 
 
class B(Base):
    def __init__(self):
        print("enter B")
        super(B,self).__init__()
        print("leave B")
 
class C(A,B):
    def __init__(self):
        print("enter C")
        super(C,self).__init__()
        print("leave C")
 
 
c=C()

  运行结果:

enter C
enter A
enter B
enter Base
leave Base
leave B
leave A
leave C

  可见,父类多次被调用时只执行一次, 优化了执行逻辑。

  具体原因可以看看张同学软件开发写的:彻底搞懂python super函数的作用

三、文件

3.1文件

  使用文件的目的:保存数据存放在磁盘,把一些存储存放起来,可以让程序下一次执行的时候直接使用,而不必重新制作一份,省时省力

3.2文件的打开与关闭

 

3.3文件的读写

# read() 读文件
# 把硬盘里的文件加载到内存中
f = open('test.txt', 'r')
# print(f.read()) 读取文件内所有内容
print(f.read(5))  # 读取5个
print(f.read())  # 读取文件剩余内容
f.close()
# 当文件足够大的时候,内存不够加载整个文件
# 需要一部分一部分加载
f = open('test.txt', 'r')
print(f.readline()) # 读取一行数据
print(f.readlines())  # 读取所有行
f.close()
# 读取汉字时会乱码,需要设置编码格式
f = open('test.txt', 'r', encoding="utf-8")
print(f.readlines())  # 读取所有行
f.close()

# 写数据
# w 如果文件存在,则将其覆盖
f = open('test.txt', 'w')
f.write('hello word, I am zhang')
f.close()

3.4文件、文件夹的相关操作

 

# OS中的rename(需要修改的文件名,新的文件名)可以完成对文件的重命名操作
import os
os.rename("test-复件.txt", "test1.txt")

# OS模块中的remove(待删除的文件名)可以完成对文件的删除操作
os.remove("test1.txt")

# OS模块中的mkdir(文件夹名)可以创建新的文件夹
os.mkdir("a")

# 获取当前目录
os.getcwd()

# 改变默认目录
os.chdir("../")

# 获取目录列表(目录中的所有文件)
print(os.listdir("./"))

# 删除文件夹
os.rmdir("./a")

3.5 应用

# 文件的备份
# 复制文件 test.txt 文件 到test-复件.txt
# 1.获取源文件的名字(包括路径)
filename = input("请输入要备份文件的名称:")
# 2.打开原文件
oldFile = open(filename, "rb")
# 3.获取备份文件的名字 备份文件名字 = 源文件名字 + ”-复件“ + 后缀名
fileFlagNum = filename.rfind(".")  
# 从右往左找找到的必是后缀名(从左往右可能会遇到text.text.txt这种情况) fileFlag = filename[fileFlagNum:] newFileName = filename[:fileFlagNum]+"-复件"+fileFlag# 4.写入备份文件 newfile = open(newFileName,"wb") for linecountent in oldFile.readlines(): newfile.write(linecountent) # 5.关闭文件释放资源 oldFile.close() newfile.close()
#批量在文件名前加前缀
import os

folderName = './aa/'
# 1.获取指定路径的所有文件名宁
dirlist = os.listdir(folderName)
# 2.遍历输出所在文件名字
for name in dirlist:
        newName = '[猫熊出品]-'+ name
os. rename ( folderName+name, folderName+newName )

四、异常处理

4.1 异常

  当Python检测到一个错误时,解释器就无法继续执行了,反而出现了一些错误的提示, 这就是所谓的"异常”

4.2 捕获异常

  

  可能产生的异常的代码,放在try中。如果产生异常,处理的方法放在except中。

  此处as的作用可以看后文,4.4注。

4.3异常的传递

  

 

 

   通过嵌套,实现异常向外传递。如果里面的try没有捕获到这个异常,那么外面的try会接收到这个异常,然后进行处理,如果外边的try依然没有捕获到,那么再进行传递。

  

  如果一个异常是在一个函数中产生的,例如函数A---->函数B---->函数C,而异常是在函数C中产生的,那么如果函数C中没有对这个异常进行处理,那么这个异常会传递到函数B中,如果函数B有异常处理那么就会按照函数B的处理方式进行执行;如果函数B也没有异常处理,那么这个异常会继续传递,以此类推......如果所有的函数都没有处理,那么此时就会进行异常的默认处理,即通常见到的那样。
  如图,test1函数内部产生了异常,异常在test1中没有处理,于是此异常被传递到test3函数完成异常处理,而当异常处理完后,并没有返回到函数test1中进行执行,而是在函数test3中继续执行。

4.4 抛出自定义的异常

  可以用raise语句来引发一个异常。异常/错误对象必须有一个名字,且它们应是Error或Exception类的子类。

class ShortInputException(Exception):
    '''自定义的异常类'''

    def __init__(self, length, atleast):
        super().__init__()
        self.length = length
        self.atleast = atleast

    def __str__(self):  # 使用as查看异常信息的时候,print不会打印任何内容,需要添加一个__str__()使其能够打印出想要的信息
        return 'ShortInputException: 输入的长度是 %d,长度至少应是 %d' % (self.length, self.atleast)
def main():
    try:
        s = input('请输入 --> ')
        if len(s) < 3:
            # raise引发一个你定义的异常
            raise ShortInputException(len(s), 3)
    except ShortInputException as result:  # x这个变量被绑定到了错误的实例
        print(result)
    else:
        print('没有异常发生.')
main()

     注:as声明了一个将保存exception对象的变量。如果说except Exception as e,那么e将是Exception类型的对象。

五、模块和包

5.1 模块

  有过C语言编程经验的朋友都知道在C语言中如果要引用sgrt函敬 ,必须用语句#include <math.h> 引math.h这个头文件,否则是无法正常进行调用的。

  那么在Python中,如果要引用一些其他的函数,该怎么处理呢?

  在Python中有一个概念叫做模块(module) ,模块是在函数和类的基础上,将一系列相关代码组织到一起的集合体。在 Python 中,一个模块就是一个扩展名为 .py 的源程序文件。这个和C语言中的头文件以及Java中的包很类似,比如在Python中要调用sqrt用数,必须用import关键字引入math这个模块,下面就来了解一下Python中的模块。说的通俗点:模块就好比是工具包,要想使用这个工具包中的工具(就好比函数),就需要导入这个模块

  

5.2 模块制作

  

 

 

   

5.3模块中的__all__

  如果想要以from 自定义包名 import *,需要在包中的__init__.py文件中使用__all__

  

 

 

   建议使用精准导入,多个可以使用逗号隔开。

  

 

 

   重名可以使用as起个别名

5.4包

  

 

 

   

 

 

 

 

  

标签:__,文件,函数,python,self,Base,print,父类
来源: https://www.cnblogs.com/tenyuan/p/16493638.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有