函数、类、模块
函数
定义函数
Python 定义函数使用 def 关键字,一般格式如下:
def 函数名(参数列表):
函数体
def modify_name(filename):
filename += ".txt"
filename = "my_" + filename
print(filename)
modify_name("f1")
modify_name("f2")
输出:
my_f1.txt
my_f2.txt
函数也可以没有输入参数
def my_func():
filename = "f1"
ext = ".txt"
total_name = filename + ext
print(total_name)
my_func()
输出:
f1.txt
像上面的功能,还想拿出来函数处理的结果,其实也就是让函数 return 一个值。
def modify_name(filename):
filename += ".txt"
filename = "my_" + filename
return filename
new_filename = modify_name("f1")
print(new_filename)
输出:
my_f1.txt
参数设置
def f(x, a, b, c):
return a*x**2 + b*x + c*1
print(f(2, 1, 1, 0)) # 忽略参数名,按顺序传参
print(f(x=2, a=1, b=1, c=0)) # 写上参数名,按名字传参
print(f(a=1, c=0, x=2, b=1)) # 若用参数名,可以打乱顺序传参
输出:
6
6
6
在参数多的时候最好把参数名也写上,避免搞混了。
另外,有些函数的参数并不是一直变化的,可以设置一个参数默认值,节省写代码的时间和代码量。
如果设置了这些默认值,那在调用函数的时候就不一定要给这个参数赋值了。
如果没有设置默认值,每个参数都要传入才能成功调用
def f(x, a=1, b=1, c=0): #设置默认参数值
return a*x**2 + b*x + c*1
print(f(2, a=2)) #默认参数值可以修改
print(f(2))
输出:
10
6
类
定义类
用 class File 来创建一个类
注意通常约定类的名字要首字母大写。
class classname[(父类名)]:
– 成员函数及成员变量
_ init _ 构造函数:初始化对象
_ del_ 析构函数:销毁对象
然后用 my_file = File() 来创建一个具体的文件。 每个具体的个体都带有这个类的基本属性,如 create_time, name。
class File:
def __init__(self):
self.name = "f1"
self.create_time = "today"
my_file = File()
print(my_file.name)
print(my_file.create_time)
输出:
f1
today
类的方法与普通的函数只有一个特别的区别——必须有一个额外的第一个参数名称, 按照惯例它的名称是 self。
self 是作为类自己的一个索引,不管你在定义类的时候,想要获取这个类的什么属性或功能,都可以通过 self 来获取。
比如上面的 File 类中,获取类自己的 create_time,就写成了 self.create_time。之后在说类的功能的时候, 也是通过 self 来在类内部调用的。
每进行一次 my_file = File() 这种操作的时候,把类给实例化的时候, File 类都会触发一次 __init__ 功能,所以__init__()是一个功能,用于初始化一些设置。
有了这些属性,我们就能获取属性,也能修改属性的值。
my_file.name = "new_name"
print(my_file.name)
输出:
new_name
类的功能
类的功能类似于函数功能
比如在 __init__() 里加上传入参数。并且在初始化 File() 的时候传入你要 __init__ 的参数。
class File:
def __init__(self, name, create_time="today"):
self.name = name
self.create_time = create_time
my_file = File("my_file")
print(my_file.name)
print(my_file.create_time)
输出:
my_file
today
当然还可以定义更多的功能
其实重命名是文件操作的一种基本功能, 所以我们将重命名标准化成一个类的功能,让所有实例都能用上。
class File:
def __init__(self, name, create_time="today"):
self.name = name
self.create_time = create_time
def change_name(self, new_name):
self.name = new_name
my_file = File("my_file")
print(my_file.name)
# 调用实例中,类的功能
my_file.change_name("new_name")
print(my_file.name)
输出:
new_name
类的功能也是可以有返回值的。
类的功能定义,相比普通的函数定义, 除了多出了一个 self,其他的并没有多大区别,
class File:
def __init__(self, name, create_time="today"):
self.name = name
self.create_time = create_time
def get_info(self):
return self.name + "is created at" + self.create_time
my_file = File("my_file")
print(my_file.get_info())
输出:
my_fileis created at today
继承
可以通过继承的方式,将细分类嵌入到抽象类中,减少共有属性/功能的重复开发。
比如定义文本文件和视频文件,如果分开定义两个类,可以这样写:
class Video:
def __init__(self, name, window_size=(1080, 720)):
self.name = name
self.window_size = window_size
self.create_time = "today"
class Text:
def __init__(self, name, language="zh-cn"):
self.name = name
self.language = language
self.create_time = "today"
这两种文件,其实是有共性的,比如他们都有 name,其实他们还可以抽象出一个更底层的类, 也就是文件类。这个文件类包含了属于文件所具备的共同属性和功能。
class File:
def __init__(self, name, create_time="today"):
self.name = name
self.create_time = create_time
def get_info(self):
return self.name + "is created at" + self.create_time
class Video(File): # 继承了 File 的属性和功能
def __init__(self, name, window_size=(1080, 720)):
# 将共用属性的设置导入 File 父类
super().__init__(name=name, create_time="today")
self.window_size = window_size
class Text(File): # 继承了 File 的属性和功能
def __init__(self, name, language="zh-cn"):
# 将共用属性的设置导入 File 父类
super().__init__(name=name, create_time="today")
self.language = language
# 也可以在子类里复用父类功能
def get_more_info(self):
return self.get_info() + ", using language of " + self.language
v = Video("my_video")
t = Text("my_text")
print(v.get_info()) # 调用父类的功能
print(t.create_time) # 调用父类的属性
print(t.language) # 调用自己的属性
print(t.get_more_info()) # 调用自己加工父类的功能
输出:
pmy_videois created attoday
today
zh-cn
my_textis created attoday, using language of zh-cn
简单的说super().__init__(),就是继承父类的init方法,同样可以使用super()去继承其他方法。
私有属性和功能(初学者了解)
class File:
def __init__(self):
self.name = "f1"
self.__deleted = False # 我不让别人用这个变量
self._type = "txt" # 我不想别人使用这个变量
def delete(self):
self.__force_delete()
def __force_delete(self): # 我不让别人使用这个功能
self.__deleted = True
return True
def _soft_delete(self): # 我不想让别人使用这个功能
self.__force_delete() # 我自己可以在内部随便调用
return True
f = File()
print(f._type) # 可以拿到值,但是这个类的作者不想让你直接这样拿到
print(f._soft_delete()) # 可以调用,但是这个类的作者不想让你直接调用
# 接下来的两个实验都会报错
# f.__deleted
# f.__force_delete()
输出:
txt
True
| 私有 | 特点 |
|---|---|
| _ 一个下划线开头 | 弱隐藏 不想让别人用 (别人在必要情况下还是可以用的) |
| __ 两个下划线开头 | 强隐藏 不让别人用 |
私有属性通常是你为别人开发项目的时候才要考虑的。 有的属性或者功能,你不需要让别人知道,也不需要让别人调用,纯属自己开发时才会用到的一些东西, 所以就可以用私有化,强隐藏或者弱隐藏起来。
Module 模块
module主要是为了一个相对比较大的工程,涉及到多个文件之间的互相调用关系。 如果一个文件写所有的代码可能成千上万行,阅读起来一点也不友善, 所以大多情况是将大项目的长代码拆开成多个模块,用文件夹和多文件的方式管理起来,方便后期维护。 这就有了 module 模块的程序代码管理方式。
引用Module
引用 module,我们通常也可以说成 引用库,引用包,引用代码 等。总之就是引用一份已经写好的代码。
# file.py
def create_name():
return "new_file.txt"
# me.py
import file
print(file.create_name())
输出:
new_file.txt
引用 file.py 这个文件的写法是 import file。 而调用 file.py 里的 create_name() 的写法是 file.create_name()。
这里调用模块功能的时候和调用Python类功能更有异曲同工之处。甚至下面换一种方式,会觉得更像了。
# me.py
import file as f1
print("f1:", f1.create_name())
class File:
def create_name(self):
return "new_file.txt"
f2 = File()
print("f2:", f2.create_name())
输出:
f1: new_file.txt
f2: new_file.txt
写 import file as f1 可以给模块重命名
其他引用方式:
# me.py
from file import create_name, create_time
print(create_name())
print(create_time())
输出:
new_file.txt
# me.py
# 第一种,之前介绍了
import file
print("1", file.create_name())
# 第二种更偷懒
from file import *
print("2", create_name())
print("2", create_time())
输出:
new_file.txt
today