Python——函数、类、文件与异常

函数

一.创建和调用

1.定义

执行特定任务以完成特定功能的一段代码
优点:复用代码、隐藏实现细节、提高可维护性、提高可读性便于调试

2.创建

def 函数名(参数):
	"""显示简单的问候语"""
	函数内容
def calc(a,b):
    c=a+b
    return c

result=calc(20,30)
print(result)#50

3.实参(‘alice in wonderland’)、形参(bookname)

def favorite_book(bookname):
	print("one of my favorite books is"+bookname.title()+"!")
favorite_book('alice in wonderland')

二.参数传递

1.位置实参

实参顺序与形参顺序相同

def describe_pet(animal_type, pet_name):
    """显示宠物的信息"""
    print("\nI have a "+animal_type+".")
    print("My "+animal_type+"'s name is "+pet_name.title()+".")
describe_pet('hamster', 'harry')#I have a hamster.
                                #My hamster's name is Harry.

2.关键字实参:指出给哪个形参即可

每个实参都由变量名和值组成,还可使用列表和字典

def describe_pet(animal_type, pet_name):
    """显示宠物的信息"""
    print("\nI have a "+animal_type+".")
    print("My "+animal_type+"'s name is "+pet_name.title()+".")
describe_pet(pet_name='harry',animal_type='hamster' )#I have a hamster.
                                                     #My hamster's name is Harry.

3.形参可以有默认值

def describe_pet(pet_name, animal_type='dog'):
    """显示宠物的信息"""
    print("\nI have a "+animal_type+".")
    print("My "+animal_type+"'s name is "+pet_name.title()+".")
describe_pet('willie')#I have a dog.
                      #My dog's name is Willie.

4.内存分析

def fun(arg1,arg2):
    print('arg1',arg1)
    print('arg2',arg2)
    arg1=100
    arg2.append(10)
    print('arg1', arg1)
    print('arg2', arg2)

n1=11
n2=[22,33,44]
print('n1', n1)#n1 11
print('n2', n2)#n2 [22, 33, 44]
fun(n1,n2)#实参名称可以跟形参名称不一致
          #arg1 11
          #arg2 [22, 33, 44]
          #arg1 100
          #arg2 [22, 33, 44, 10]
print('n1', n1)#n1 11
print('n2', n2)#n2 [22, 33, 10]
               # 在函数的调用过程中进行参数传递
               # 如果是不可变对象,在函数体的修改中不会影响实参的值 arg1的修改不会影响n1的值
               # 如果是可变对象,在函数体的修改中会影响实参的值 arg2的修改不会影响n2的值

三.返回值:return

如果函数没有返回值,return可以省略不写
如果有一个返回值,返回原类型
如果有多个返回值,返回元组

1.实参可选

指定一个默认值——空字符串

def get_formatted_name(first_name, last_name, middle_name=''): 
    """返回整洁的姓名"""
    if middle_name: 
        full_name = first_name+' '+middle_name+' '+last_name
    else: 
    	full_name = first_name+' '+last_name
    return full_name.title()
musician = get_formatted_name('jimi', 'hendrix')
print(musician)#Jimi Hendrix
musician = get_formatted_name('john', 'hooker', 'lee')
print(musician)#John Lee Hooker

2.返回字典

def build_person(first_name, last_name, age=''):
    """返回一个字典,其中包含有关一个人的信息"""
    person = {'first': first_name, 'last': last_name}
    if age:
        person['age'] = age
    return person
musician = build_person('jimi', 'hendrix', age=27)
print(musician)#{'first': 'jimi', 'last': 'hendrix', 'age': 27}

3.返回元组

def fun1(num):
    odd=[]
    even=[]
    for i in num:
        if i%2:
            odd.append(i)
        else:
            even.append(i)
    return odd,even

print(fun1([10,29,34,23,44,53,55]))#([29, 23, 53, 55], [10, 34, 44])

四.传递列表

1.在函数中修改列表

pop 像弹出栈顶,永久修改

def print_models(unprinted_designs,completed_models):
	"""
	模拟打印每个设计,直到没有未打印的设计为止
	打印每个设计后,都将其移到列表completed_models中
	"""
	while unprinted_designs:
    	current_design = unprinted_designs.pop()
   		#模拟根据设计制作3D打印模型的过程
    	print("Printing model: "+current_design)
    	completed_models.append(current_design)

def show_completed_models(completed_models):
	"""
	显示打印好的所有模型
	"""
	print("\nThe following models have been printed:")
	for completed_model in completed_models:
   		print(completed_model)

unprinted_designs = ['iphone case', 'robot pendant', 'dodecahedron']
completed_models = []
print_models(unprinted_designs,completed_models)
show_completed_models(completed_models)

2.禁止函数修改列表

传副本 [:],要消耗时间和内存

print_models(unprinted_designs [:],completed_models)

五.参数定义

1.个数可变的位置参数 只能是一个

①定义函数时,无法实现确定位置实参的个数,使用可变的位置参数
②使用*定义个数可变的位置参数
③结果为一个元组

def fun2(*args):
    print(args)

fun2(10)#(10,)
fun2(10,30,50)#(10, 30, 50)

2.个数可变的关键字形参 只能是一个

①定义函数时,无法实现确定关键字实参的个数,使用可变的关键字形参
②使用**定义个数可变的关键字形参
③结果为一个集合

def fun3(**args):
    print(args)

fun3(a=10)#{'a': 10}
fun3(a=10,b=30,c=50)#{'a': 10, 'b': 30, 'c': 50}

3.既有1又有2,1放在2前可以

4.函数的参数总结

在这里插入图片描述

def fun4(a,b,c):
    print(a)
    print(b)
    print(c)
#①
lst=[11,22,33]
fun4(*lst)#在函数调用时,将列表每个元素转换为位置实参
#②
dic={'a':111,'b':222,'c':333}
fun4(**dic)#在函数调用时,将字典中的键值对都转换为关键字实参
#③
def fun5(a,b,*,c,d):#c、d只能采用关键字实参传递
    print(a,b,c,d)
fun5(10,20,d=30,c=40)

六.将函数存储在模块中:import

1.导入整个模块

pizza.py

def make_pizza(size, *toppings):
    """概述要制作的比萨"""
    print("\nMaking a "+str(size)+
          "-inch pizza with the following toppings:")
    for topping in toppings:
        print("- "+topping)

making_pizzas.py
使用:模块名.函数名

import pizza
pizza.make_pizza(16, 'pepperoni') 
pizza.make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')

2.导入特定函数

from 模块名 import 函数名1,函数名2,函数名3(变量、类也可)
调用:函数名(实参)

3.导入所有函数

from 模块名 import *
调用:函数名(实参)
*不建议使用,很可能导入的函数与项目中的名称相同 *

4.使用as给函数指定别名

from 模块名 import 函数名 as 别名
调用:别名(实参)

5.使用as给模块指定别名

import 模块名 as 别名
调用:别名.函数名(实参)

一.创建类和使用类

class Dog(): 
    """一次模拟小狗的简单尝试""" 
    def __init__(self, name, age): 
        """初始化属性name和age"""
        self.name = name 
        self.age = age
    def sit(self): 
        """模拟小狗被命令时蹲下"""
        print(self.name.title()+" is now sitting.")
    def roll_over(self):
        """模拟小狗被命令时打滚"""
        print(self.name.title()+" rolled over!")

1.class 类名():

注意:类名首字母大写;括号为空代表从空白创建这个类

2.init(self,形参1,形参2)

①类每创建一个新实例,python都会自动运行它
②Python调用这个__init__()方法来创建Dog实例时,将自动传入实参self。每个与类相关联的方法调用都自动传递实参self,它是一个指向实例本身的引用,让实例能够访问类中的属性和方法。每创建一个新实例,只需要给后两个形参提供值
③可通过实例访问的变量称为属性

3.创建实例

my_dog = Dog('willie', 6) 
print("My dog's name is "+my_dog.name.title()+".") 
print("My dog is "+str(my_dog.age)+" years old.") 
my_dog.sit()
my_dog.roll_over()

二.使用类和实例

1.给属性指定默认值

在方法__init__内对某个属性指定初始值后,就无须提供形参
self.odometer_reading = 0

class Car():
    def __init__(self, make, model, year):
        """初始化描述汽车的属性"""
        self.make = make
        self.model = model
        self.year = year
        self.odometer_reading = 0 
    def get_descriptive_name(self):
        long_name = str(self.year)+' '+self.make+' '+self.model
        return long_name.title()
    def read_odometer(self): 
        """打印一条指出汽车里程的消息"""
        print("This car has "+str(self.odometer_reading)+" miles on it.")
my_new_car = Car('audi', 'a4', 2016)
print(my_new_car.get_descriptive_name())
my_new_car.read_odometer()

2.修改属性的值

①直接修改

my_new_car.odometer_reading=23
my_new_car.read_odometer()

②通过方法修改属性的值

class Car():
    def __init__(self, make, model, year):
        """初始化描述汽车的属性"""
        self.make = make
        self.model = model
        self.year = year
        self.odometer_reading = 0 
    def get_descriptive_name(self):
        long_name = str(self.year)+' '+self.make+' '+self.model
        return long_name.title()
    def read_odometer(self): 
        """打印一条指出汽车里程的消息"""
        print("This car has "+str(self.odometer_reading)+" miles on it.")
    def update_odometer(self,mileage):
    	"""将里程表读数设置为特定的值"""
    	self.odometer_reading=mileage
my_new_car = Car('audi', 'a4', 2016)
print(my_new_car.get_descriptive_name())
my_new_car.update_odometer(23)
my_new_car.read_odometer()

③通过方法对属性的值进行递增

class Car():
    def __init__(self, make, model, year):
        """初始化描述汽车的属性"""
        self.make = make
        self.model = model
        self.year = year
        self.odometer_reading = 0 
    def get_descriptive_name(self):
        long_name = str(self.year)+' '+self.make+' '+self.model
        return long_name.title()
    def read_odometer(self): 
        """打印一条指出汽车里程的消息"""
        print("This car has "+str(self.odometer_reading)+" miles on it.")
    def update_odometer(self,mileage):
    	"""将里程表读数设置为特定的值"""
    	self.odometer_reading=mileage
    def increment_odometer(self,miles)
    	"""将里程表读数增加指定的量"""
    	self.odometer_reading+=miles
my_new_car = Car('audi', 'a4', 2016)
print(my_new_car.get_descriptive_name())
my_new_car.update_odometer(23500)
my_new_car.read_odometer()
my_new_car.increment_odometer(100)
my_new_car.read_odometer()

三.继承

另一个现成类的特殊版本。一个类继承另一个类时,它将自动获得另一个类的所有属性和方法;原有的类称为父类,而新类称为子类。

1.子类方法__init__()

①定义子类必须在括号内指定父类名称
②super()函数将父类和子类关联起来

class Car():
    def __init__(self, make, model, year):
        """初始化描述汽车的属性"""
        self.make = make
        self.model = model
        self.year = year
        self.odometer_reading = 0 
    def get_descriptive_name(self):
        long_name = str(self.year)+' '+self.make+' '+self.model
        return long_name.title()
    def read_odometer(self): 
        """打印一条指出汽车里程的消息"""
        print("This car has "+str(self.odometer_reading)+" miles on it.")
    def update_odometer(self,mileage):
    	"""将里程表读数设置为特定的值"""
    	self.odometer_reading=mileage
    def increment_odometer(self,miles)
    	"""将里程表读数增加指定的量"""
    	self.odometer_reading+=miles

class ElectricCar(Car): 
    """电动汽车的独特之处"""
    def __init__(self, make, model, year): 
        """初始化父类的属性"""
        super().__init__(make, model, year) 

my_tesla = ElectricCar('tesla', 'model s', 2016) 
print(my_tesla.get_descriptive_name())

2.给子类定义属性和方法

class ElectricCar(Car): 
    """
    电动汽车的独特之处
	初始化父类的属性,再初始化电动汽车特有的属性
	"""
    def __init__(self, make, model, year): 
        """初始化父类的属性"""
        super().__init__(make, model, year) 
        self.battery_size=70
    def describe_battery(self):
    	"""打印一条描述电瓶容量的消息"""
    	print("This car has a "+str(self.battery_size)+"-kWh battery.")
my_tesla = ElectricCar('tesla', 'model s', 2016)
print(my_tesla.get_descriptive_name())
my_tesla.describe_battery()

3.重写父类方法

在子类重写

4.将实例用做属性

分出来 class Battery():
实例 self.battery = Battery()
调用方法 my_tesla.battery.describe_battery()

class Car():
    --snip--
class Battery(): 
    """一次模拟电动汽车电瓶的简单尝试"""
    def __init__(self, battery_size=70): 
        """初始化电瓶的属性"""
        self.battery_size = battery_size
    def describe_battery(self): 
        """打印一条描述电瓶容量的消息"""
        print("This car has a "+str(self.battery_size)+"-kWh battery.")

class ElectricCar(Car):
    """电动汽车的独特之处"""
    def __init__(self, make, model, year):
        """
        初始化父类的属性,再初始化电动汽车特有的属性
        """
        super().__init__(make, model, year)
        self.battery = Battery() 

my_tesla = ElectricCar('tesla', 'model s', 2016)
print(my_tesla.get_descriptive_name())
my_tesla.battery.describe_battery()

四.导入类

导入一个或多个类:from 文件名 import 类名1,类名2
导入整个模块:from 文件名
导入模块中的所有类:from 文件名 import * 不建议用

五.python标准库

创建字典并记录其中的键—值对的添加顺序,可使用模块collections中的OrderedDict类

六.类编码风格

类名应采用驼峰命名法,即将类名中的每个单词的首字母都大写,而不使用下划线。实例名和模块名都采用小写格式,并在单词之间加上下划线。
对于每个类,都应紧跟在类定义后面包含一个文档字符串

文件和异常

一.从文件读取数据

1.读整个文件

①函数open()返回一个表示文件的对象,Python将这个对象存储在我们将在后面使用的变量中。
②关键字with在不再需要访问文件后将其关闭
with语句可以自动管理上下文资源,不论什么原因跳出with块,都能确保文件正确的关闭,以此来达到释放资源的目的
③使用read()方法读取文件的全部内容
④read()到达文件末尾时返回一个空字符串,而将这个空字符串显示出来时就是一个空行。要删除末尾的空行,可在print语句中使用rstrip()
⑤变量filename表示的并非实际文件——它只是一个让Python知道到哪里去查找文件的字符串

with open('pi_digits.txt') as file_object:
    contents = file_object.read()
    print(contents.rstrip())

2.文件路径

①找相对路径
比如:文本文件(.txt)在程序文件(.py)的下一级

with open('text_files\filename.txt') as file_object:

②找绝对路径

file_path = 'C:\Users\ehmatthes\other_files\text_files\filename.txt'
with open(file_path) as file_object:

3.逐行读取

每行的末尾都有一个看不见的换行符,而print语句也会加上一个换行符,因此每行末尾都有两个换行符:一个来自文件,另一个来自print语句。要消除这些多余的空白行,可在print语句中使用rstrip()

filename = 'pi_digits.txt'
with open(filename) as file_object:
    for line in file_object:
        print(line.rstrip())

4.创建一个包含文件各行内容的列表

方法readlines()从文件中读取每一行,并将其存储在一个列表中;接下来,该列表被存储到变量lines中;在with代码块外,我们依然可以使用这个变量

filename = 'pi_digits.txt'
with open(filename) as file_object:
    lines = file_object.readlines() 
for line in lines: 
    print(line.rstrip())

5.使用文件的内容

获得圆周率的字符串

filename = 'pi_30_digits.txt'
with open(filename) as file_object:
    lines = file_object.readlines()
pi_string = ''
for line in lines:
    pi_string+= line.strip()
print(pi_string)
print(len(pi_string))

6.包含一百万为的大型文件

打印到小数点后50位

filename = 'pi_million_digits.txt'
with open(filename) as file_object:
    lines = file_object.readlines()
pi_string = ''
for line in lines:
    pi_string+= line.strip()
print(pi_string[:52]+"...")
print(len(pi_string))

二.写入文件

1.写入空文件

open(文件名,'w)
w:以写入模式打开这个文件 创建刷新
r: 以读取模式打开这个文件 默认
a:以附加模式打开这个文件 创建追加
b:以二进制方式打开文件,不能单独使用,可以rb,wb
r+:以读取和写入模式打开这个文件

filename = 'programming.txt'
with open(filename, 'w') as file_object: 
    file_object.write("I love programming.")

这个程序没有终端输出
注:Python只能将字符串写入文本文件。要将数值数据存储到文本文件中,必须先使用函数str()将其转换为字符串格式

2.写入多行

函数write()不会在你写入的文本末尾添加换行符,所以每一个字符串末尾加\n

3.附加到文件

filename = 'programming.txt'
with open(filename, 'a') as file_object: 
    file_object.write("I also love finding meaning in large datasets.\n") 
    file_object.write("I love creating apps that can run in a browser.\n")

三.异常

异常:是一个特殊对象,来管理程序执行期间发生的错误

1.处理ZeroDivisionError异常

异常是使用try-except-else代码块处理的。try-except-else代码块的工作原理大致如下:Python尝试执行try代码块中的代码;只有可能引发异常的代码才需要放在try语句中。有时候,有一些仅在try代码块成功执行时才需要运行的代码;这些代码应放在else代码块中。except代码块告诉Python,如果它尝试运行try代码块中的代码时引发了指定的异常,该怎么办。

print("Give me two numbers, and I'll divide them.")
print("Enter 'q' to quit.")
while True:
    first_number = input("\nFirst number: ")
    if first_number == 'q':
        break
    second_number = input("Second number: ")
    try: ❶
        answer = int(first_number) / int(second_number)
    except ZeroDivisionError:print("You can't divide by 0!")
    else:print(answer)

2.处理FileNotFoundError异常

方法split()以空格为分隔符将字符串分拆成多个部分,并将这些部分都存储到一个列表中

filename = 'alice.txt'
try:
    with open(filename) as f_obj:
        contents = f_obj.read()
except FileNotFoundError:
    msg = "Sorry, the file "+filename+" does not exist."
    print(msg)
else:
    # 计算文件大致包含多少个单词
    words = contents.split() ❶
    num_words = len(words)print("The file "+filename+" has about "+str(num_words)+" words.")

如果希望发生FileNotFoundError异常时一声不吭:
pass语句还充当了占位符,它提醒你在程序的某个地方什么都没有做,并且以后也许要在这里做些什么

 except FileNotFoundError:
 	pass

四.存储数据

用模块json来存储
补:JSON(JavaScript Object Notation)格式最初是为JavaScript开发的,但随后成了一种常见格式,被包括Python在内的众多语言采用

1.json.dump()存储 json.load()读取

import json
numbers = [2, 3, 5, 7, 11, 13]
filename = 'numbers.json' 
with open(filename, 'w') as f_obj: 
    json.dump(numbers, f_obj)
import json
filename = 'numbers.json' 
with open(filename) as f_obj: 
    numbers = json.load(f_obj) 
print(numbers)

2.保存和读取用户生成的数据

remember_me.py

import json
# 如果以前存储了用户名,就加载它
#  否则,就提示用户输入用户名并存储它
filename = 'username.json'
try:
    with open(filename) as f_obj: ❶
        username = json.load(f_obj)except FileNotFoundError: ❸
    username = input("What is your name? ")with open(filename, 'w') as f_obj: ❺
        json.dump(username, f_obj)
        print("We'll remember you when you come back, "+username+"!")
else:
    print("Welcome back, "+username+"!")
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

说说其实

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值