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+"!")
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,302评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,563评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,433评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,628评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,467评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,354评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,777评论 3 387
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,419评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,725评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,768评论 2 314
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,543评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,387评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,794评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,032评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,305评论 1 252
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,741评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,946评论 2 336

推荐阅读更多精彩内容