PYTHON学习笔记(三)

第八章 函数
函数的定义

def print_name(username):
    print(username+"太强了,我是伞兵")
print_name("卢姥爷")

在函数定义中有多个形参时,调用函数时的输入实参顺序显然是和形参一一对应的,但是可以用以下方法规定哪一个实参传递给哪一个形参。如下所示:

def print_name(username,friend):
    print(username+"是"+friend+"最好的朋友")
print_name("卢姥爷","凯亚")
print_name(friend="卢老爷",username="凯亚")

可见,可以使用关键字实参,规定实参传递给哪一个形参,而与输入顺序无关。

默认形参参数:

def print_name(username,friend="凯亚"):
    print(username+"是"+friend+"最好的朋友")
print_name("卢姥爷")

这样是没啥问题的,此处应该是要求和C++保持一致,无默认值的形参要写在前面,有默认值的要写在后面。

def print_name(friend="凯亚",username):
    print(username+"是"+friend+"最好的朋友")
print_name("卢姥爷")

这样的代码将会编译报错,报错信息如下,证明了我们的结论:

image

函数返回值的使用

def add_function(a, b):
    return a + b


def name_produce(firstname, secondname):
    return (firstname.title() + " " + secondname)


c = add_function(1, 2)
print(c)
wangxiaoming = name_produce("wang", "xiaoming")
print(wangxiaoming)

禁止函数修改列表:

def delete_List(list_p):
    while list_p:
        number=list_p.pop(0)
        print(number)

list_p=["123","234","3124","314125"]
delete_List(list_p[:])#如果这里用的是list_p本身,则由于是引用传递。
#list_p本身的数据会被修改。
print(list_p)

传递任意数量的实参:
有些时候,传递的参数数量是不确定的,可以采用接下来的办法:

def delete_List(*list_p):
    for number in list_p:
        print(number,end=" ")

delete_List(1,2,3,4,5,6,7,8,9,10)

如果我们使用print(list_p)可以看到 list_p是一个元组类型的数据
使用type函数也可以看出,类型是tuple

这里针对于元组tuple有一个问题,虽然大家都说元组元素不可以改变,但实际上我们可以查看下列代码:

def delete_List(*list_p):
    print(type(list_p))
    list_p[2].insert(0,12)
    print(list_p)
delete_List(('lee', 21), ('gong', 20),[1,2,3])

实际上元组的元素发生了改变,我们可以认为是元组中元组地址和对应的数据的映射是不可改变的,但是对应的数据本身可以改变。
位置形参与任意数量实参相结合比较简单,只需要确保接受不确定数量的实参的形参在后面就可以了。
接下来我们看一下使用任意数量的关键字实参。
(意思就是,实参数量不确定,并且指定了关键字)
如下:

from functools import cmp_to_key
def key_judge(x,y):
    if  x[0]>y[0]:
        return -1
    else:
        return 1
def produce_List(name, **list_p):
    list_p["name"] = name
    return list_p
newstudent = produce_List("Yin", school="HIT", graduate_year="2020")
print(sorted(newstudent.items(),  key=cmp_to_key(key_judge)))

比较复杂,并且使用了key参数,规定了排序的比较参数和比较规则,也算学了点新东西吧。

函数模块:
我们在make.py文件中写入:

def make_pizza(size, *toppings):
    print("这个pizza的尺寸是:"+str(size))
    for topping in toppings:
        print(topping)

然后我们在main.py中调用:

import make
make.make_pizza(10,"臭豆腐","腐乳","鲱鱼罐头","奥里给")

注意必须使用 make.make_pizza()的方式,否则无法识别。
如果想要直接调用make_pizza(),那么就需要加载时使用
from make import make_pizza
当然也可以使用别名,使用别名后,就不可以再使用原来的名称,别名用于防止引用的函数名和该模块内本身的函数名冲突,如下:

from make import make_pizza as oldeight
oldeight(10,"臭豆腐","腐乳","鲱鱼罐头","奥里给")
from make import make_pizza as oldeight
import make
make.make_pizza(10,"臭豆腐","腐乳","鲱鱼罐头","奥里给") #合法
oldeight(10,"臭豆腐","腐乳","鲱鱼罐头","奥里给") # 合法
make_pizza(10,"臭豆腐","腐乳","鲱鱼罐头","奥里给") #不合法 编译报错

同样可以指定模块名,例如:

import make as m
m.make_pizza(10,"臭豆腐","腐乳","鲱鱼罐头","奥里给") #合法

如果想要使用from xxx import xxx的格式导入所有函数,可以使用这样的格式来实现。

from make import *

第九章 类


类的基本定义:

class Example:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def print_name(self):
        print(self.name)

    def print_age(self):
        print(self.age)

xiaoming=Example("xiaoming",18)
xiaoming.print_name()
xiaoming.print_age()

务必注意,类定义时,必须定义__init__()函数,并且其必须有self形参,作为创建该类对象时必须执行的函数,同时如果自定义其他函数,定义时也应当填入self形参。

简单的类编写示范:

class Example:
    def __init__(self, name, university,age=18):
        self.__name = name
        self.__age = age
        self.__university=university

    def print_name(self):
        print(self.__name)

    def print_age(self):
        print(self.__age)

    def print_university(self):
        print(self.__university)

    def updata_allinformation(self,newname,newage,newuniversity):
        self.__name=newname
        self.__updata_age(newage)  #调用自己的方法还是要写上self
        self.__updata_university(newuniversity)  #调用自己的方法要用self

    def __updata_age(self, newage):
        self.__age = newage
        self.age=newage

    def __updata_university(self, new_university):
        self.__university = new_university

student1=Example("Wang XiaoLang","HIT")
student1.print_age()
student1.print_university()
student1.print_name()
#print(student1.age)  由于我将age设置为了私有变量,从类外是不可以访问的
student1.updata_allinformation("Wang XiaoLang",22,"UESTC")
student1.print_age()
student1.print_university()
student1.print_name()
print(student1.age) #这里又可以了,因为我在updata里面额外添加了这样一个变量

继承:
python中似乎没有 JAVA 和 C++ 中复杂的 public,private,protected继承,(大概,这个继承非常的混乱(我个人认为),因为即使是私有属性依然可以强制访问)

下面是示例代码:

class Example():
    def __init__(self, name, university,age=18):
        self.__name = name
        self.__age = age
        self.__university=university
        self.ceshi=120
    def print_name(self):
        print(self.__name)

    def print_age(self):
        print(self.__age)

    def print_university(self):
        print(self.__university)

    def print_ceshi(self):
        print(self.ceshi)

    def updata_allinformation(self,newname,newage,newuniversity):
        self.__name=newname
        self.__updata_age(newage)  #调用自己的方法还是要写上self
        self.__updata_university(newuniversity)  #调用自己的方法要用self

    def __updata_age(self, newage):
        self.__age = newage
        self.age=newage

    def __updata_university(self, new_university):
        self.__university = new_university

class P_student(Example):
    def __init__(self,name,university,age=18):
        super().__init__(name, university, age)
        self.number=1
        print(self.ceshi)
        self.ceshi=120 #这里表明父类和子类的同名ceshi是一个变量 即使将这行
                                #挪到初始化之前也是如此
        super()._Example__updata_age(19)  #强制调用私有函数
        super().print_ceshi()
        super().print_age()
        self._Example__age=20  #强制调用私用变量
        super().print_age()


student1=P_student("王刚","清华大学",12)

类继承的进一步测试:

class A:
    def __init__(self):
        self.A=1
        self.B=2
    def addP(self):
        print(self.A+self.B)
    def printAB(self):
        print(self.A)
        print(self.B)

class B(A):
    def __init__(self):
        super().__init__()
        self.A=10
        A.printAB(self)  #此处输出表明 上述A和父类中A是同一个对象

b=B()

类中嵌套使用其他类的对象,这里就不展开了。
类函数的重载也很简单,重载之后的方法将覆盖父类方法,也就是只会执行重载的函数内代码,忽略原父类函数内容,
此处为测试:

class A:
    def __init__(self):
        self.A=1
        self.B=2
    def addP(self):
        print(self.A+self.B)
    def printAB(self):
        print(self.A)
        print(self.B)

class B(A):
    def __init__(self):
        super().__init__()
        self.A=10
        A.printAB(self)  #此处输出表明 上述A和父类中A是同一个对象
    def printAB(self):
        print(self.A,end="???")
        print(self.B,end=">>>")

b=B()
b.printAB() #简单的函数重载

但如果参数数量不一致呢,是否可以做到函数重载?

class A:
    def __init__(self):
        self.A=1
        self.B=2
    def addP(self):
        print(self.A+self.B)
    def printAB(self):
        print(self.A)
        print(self.B)
    def printAB(self,C):
        print(self.A)
        print(self.B)
        print(C)

b=A()
b.printAB(9)
b.printAB() #无法执行,后定义的printAB完全覆盖了前者,也就是python中不存在参数的差别产生的重载

然后是子函数重载父函数,但是参数个数不一样的实验:

class A:
    def __init__(self):
        self.A=1
        self.B=2
    def addP(self):
        print(self.A+self.B)
    def printAB(self):
        print(self.A)
        print(self.B)

class B(A):
    def __init__(self):
        super().__init__()
        self.A=10
        A.printAB(self)  #此处输出表明 上述A和父类中A是同一个对象
    def printAB(self,C):
        print(self.A,end="???")
        print(self.B,end=">>>")
        print(C)

b=B()
b.printAB(9)
b.printAB() #同样无法执行,可见python重载只要函数名相同,
            #直接覆盖父类函数。
            #与参数个数完全无关

最后是 类的导入:
显然导入单个类和导入函数本质上没有区别。
直接测试嵌套导入:
第一种 Aclass.py文件:

class A:
    def __init__(self):
        self.a=1
    def printA(self):
        print(self.a)

Bclass.py文件

from Aclass import A
class B(A):
    def __init__(self):
        A.__init__(self)
        self.b=2
        A.printA(self)

main.py文件

from Bclass import B
b=B() #正确执行,可以看到的是 即使只是显示的导入了B,
      #其依然可以使用B类中继承A类的函数

第二种测试:
将Aclass文件删除,Bclass文件修改为如下:

class A:
    def __init__(self):
        self.a=1
    def printA(self):
        print(self.a)

class B(A):
    def __init__(self):
        A.__init__(self)
        self.b=2
        A.printA(self)

在main文件不做出修改的情况下,依然可以正确执行,可见导入模块时,如果只导入子类,父类中的公有函数还是可以正常使用。

标准库代码:
随机数生成器

from random import randint
i=0
while i<99:
    i+=1
    print(randint(1,100))  #包括1和100

列表 元素随机选择一项:

from random import randint
from random import choice
i=0
example=[]
for i in range(0,10):
    example.append(i)
while i<99:
    i+=1
    print(choice(example))  #包括1和100

第十章


文件与异常:
文件访问是一个任何语言里都很常见的东西了,从C++的read/write 到java的buffer(我都记不清是啥了),反正多多少少都要用到这些东西,我们来看看Python是如何实现这些内容的吧。

首先新建一个文件夹叫 Txt 然后放入文本文件 example.txt
写入文本:

如果大海能够
带走我的哀愁
就像带走每条河流
所有受过的伤
所有流过的泪
我的爱
请全部带走

main.py内容如下:

with open("Txt\example.txt",encoding="utf-8") as file1:
    content=file1.read()
    print(content)

如果不加上encoding="utf-8"会出现乱码错误。(别人只是乱码,python直接报错无法读取)

读取文件的每一行数据:

with open("Txt\\example.txt",encoding="utf-8") as file1:
    for line in file1:
        print(line.strip())

将每一行数据 分别读取存成一个数组:

with open("Txt\\example.txt",encoding="utf-8") as file1:
    lines=file1.readlines()
for line in lines:
    print(line)

文件的写入:

file_name = "Txt\\example1.txt"
with open(file_name,'w',encoding="utf-8") as file1:
    file1.write("你好,再见")

但是 write函数并不会在输入数据的末端自动添加 换行符,也就是如果连续使用write函数(不手动使用换行符),所有的数据将保留在同一行。

同样,如果不使用“w”方式打开文件,而是使用“a”类型时,使用write函数时,数据将添加到文件的末尾,而不会清除源文件的内容。

文件指针位置调整:
seek函数和tell函数,tell函数不需要额外参数,其返回当前文件指针位置,而seek函数需要两个参数,分别是offset和whence,offset表示偏移量,当offset不为0时,要求文件必须以二进制格式打开,否则报错,whence共有三种参数选择,为0时表示文件头,1表示当前位置,2表示文件尾。

异常处理:

try:
    a=input("请输入被除数:\n")
    b=input("请输入除数:\n")
    answer=int(a)/int(b)
except ZeroDivisionError as ex1 :
    print("sorry 出错了")
    print(type(ex1),"::",ex1)
else:
    print(answer)

python可以通过pass来 表示什么都不做,从而跳过一部分需要执行代码的区域。

使用json文件实现 信息的存储和读取:

import json

file_name="example2.txt"
stringx=[]
stringx=input().split()
with open(file_name,'w',encoding="utf-8") as file1:
    json.dump(stringx,file1)
with open(file_name,'r',encoding="utf-8") as file2:
    stringx2=json.load(file2)
    print(stringx2)

实例使用

import json

file_name="example2.txt"
try:
    with open(file_name) as file1:
        numbers=json.load(file1)
except:
    print("您好,新用户,请输入您的名字")
    numbers=input()
    with open(file_name,'w') as file2:
        json.dump(numbers,file2)
else:
    print("欢迎回来"+numbers+"!")
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容