文章目录
- 一、类
- 1.1、类的定义
- 1.2、类变量和实例变量
- 1.3、类的继承
- 二、异常处理
- 三、模块 和 包
- 3.1、模块和包的概念,以及项目的树形结构
- 3.2、模块和包的使用 (from import)
- 方法一:from 模块 import 变量/函数/类
- 方式二:from 模块 import 变量名 as 其他变量名
- 方式三:from 包.模块 import 变量/函数/类
- 方式四:from 包 import 模块
- 方式五:import 变量/函数/类
- 3.3、import 和 from...import 的区别
- 3.4、包的管理 (通过命令行)
一、类
类 可以将 变量、函数 打包 在一起,让代码在逻辑上更加清晰。
类名称 一般采用 驼峰命名法 (如 GetName),函数 一般采用 下划线命名法 (如 get_name)。
类 中 函数 的 第一个参数都是 self,用来 调用类本身的变量和函数 ()。
当 调用 类中 函数 的时候,第一个 参数 self 不需要 自己传递,Python 会自动传递这个参数。
1.1、类的定义
Python 中类的函数的写法是非常灵活的,一般来说不会报错,但是一般遵循一些约定俗成的规则:
- 每个函数中第一个参数都是
self
self
这个单词本身是可以随意改变的,但是一般就用self
。self
可以理解为指向这个类的空间,用来调用这个类本身的 变量和函数。 - 调用变量的时候,不需要手动传递
self
参数
从下面的代码中可以看出,在 创建 类中的函数时,是一定要将 形参self
写出来的。但是在 调用 时,不用手动写self
对应的实参,这是 python 自动实现的。 - python 中定义了很多以 下划线 开头的函数
这里介绍两个最常用的:
函数名 | 功能 |
---|---|
__init__ | 和其他语言中的 构造函数 是一样的,初始化 的时候会 自动调用 |
_str__ | 用来定义 str(类名) 这个函数的效果的 |
class Hero:hero_count = 0 # 类变量def __init__(self, name, level=10): # 构造函数self.name = nameself.level = levelprint("Hero %s has been created." % name)Hero.hero_count += 1def __str__(self): # 定义str()函数的效果return "Hero: %s" % self.namedef greet(self): # 问候print("%s: Hi!" % self.name)def move(self): # 移动print("%s: Move!" % self.name)def get_level(self): # 获取这个英雄的等级return self.leveldef next_level(self):return self.get_level() + 1 # 调用类中的其他函数
1.2、类变量和实例变量
每个类 可以创建 任意多实例。例如上面的 Hero 类,可以创建 zeus 和 athena 等 实例 (等价于其他语言中的 对象)。
类变量 由 所有实例 共享 (类似于全局变量),一般 通过类名 访问,例如 Hero.hero_count
。
实例变量 与每个 具体的实例 绑定 (类似于局部变量),一般 通过具体实例 访问,例如 zeus.name
。
对于如何 创建实例,如下所示,其遵循了一些规则:
- 在创建实例的时候,
self
是 Python 自动帮我们填的,不用手动写 - 在传输除了
self
之外的参数时,与 函数那一章形参的初始化方式 一样 str(类)
和类
是一样的效果,也就是说,当只写类名的时候,等于调用了str
函数 (下面的代码中可以看到__str__
函数的调用方式是str(zeus)
,如果自己还定义了一个str
函数,则调用方法应该是zeus.str()
zeus = Hero("Zeus")
athena = Hero("Athena", 6)
zeus.greet()
athena.move()
print(zeus.name, athena.get_level(), athena.next_level())
print(str(zeus), athena)
print(Hero.hero_count, zeus.hero_count, athena.hero_count)
"""output
Hero Zeus has been created.
Hero Athena has been created.
Zeus: Hi!
Athena: Move!
Zeus 6 7
Hero: Zeus Hero: Athena
2 2 2"""
1.3、类的继承
子类 可以 继承 父类的变量和函数。
self
可以调用 自身和父类 中的 变量和函数,super()
可以调用 父类 中的 函数。
如果 子类和父类 的变量或函数 重名,优先 使用 子类 的变量和函数。在调用某个类中的变量或函数的时候,基本过程就是 先看看该类中有没有,没有的话就看看父类中有没有。
class Hero:hero_count = 0 # 类变量def __init__(self, name, level=10): # 构造函数self.name = nameself.level = levelprint("Hero %s has been created." % name)Hero.hero_count += 1def __str__(self): # 定义str()函数的效果return "Hero: %s" % self.namedef greet(self): # 问候print("%s: Hi!" % self.name)def move(self): # 移动print("%s: Move!" % self.name)def get_level(self): # 获取这个英雄的等级return self.leveldef next_level(self):return self.get_level() + 1 # 调用类中的其他函数class Zeus(Hero):hero_name = "Zeus"def __init__(self, level):super().__init__(Zeus.hero_name, level) # 通过 super() 调用父类的构造函数,如果这里用 self,# 则调用的 __init__ 是自己的,而不是父类的,# 可以试一下实参中的 Zeus.hero_name 可不可以换成 self.hero_name (答案是可以的)def greet(self):print("%s: Hi!(from child class)" % self.name) # 使用的是父类的`name`class Athena(Hero):hero_name = "Athena"def __init__(self, level):super().__init__(Athena.hero_name, level) # 通过super()调用父类的构造函数def greet(self):print("%s: Hi!(from child class)" % self.name) # 使用的是父类的`name`
二、异常处理
当某段代码 出现异常时,代码会被 终止。此时如果 不想让代码终止,可以用 try ... except ...
语句来 自己处理异常,并且执行异常语句之后的语句。
例如,将字符串转化成整数时,可能会出现异常:
s = input()try:x = int(s)print(x)
except Exception as e: # Exception 是一个通用的异常print(e)print("Finished!")
"""output
invalid literal for int() with base 10: 'as'
Finished!"""
如果想要在异常的时候输出更加详细的内容,可以这样:
x, y = map(int, input().split())try:z = x / yprint(z)
except Exception as e:from traceback import print_excprint_exc()print("Finished!")
"""output
Traceback (most recent call last):File "E:\Jztop\PythonProject\for_learning\main.py", line 4, in <module>z = x / y
ZeroDivisionError: division by zero
Finished!"""
详细内容可以看别人的博客
三、模块 和 包
3.1、模块和包的概念,以及项目的树形结构
一个 python 的文件 (.py) 就叫做 模块 (module),如 xxx.py。模块 就是一组功能的集合体,我们的程序可以导入模块来复用模块里的功能。
一个包含有 init.py 文件的 目录或文件夹 就叫做 包 (package)。在 pycharm 中选择 python package 创建的目录就是一个包。
当项目的逻辑越来越复杂时,把所有代码写到 一个文件 中会相当不方便。此时就可以将不同代码放到 不同的模块 中。所有模块通过 文件夹和文件 组织成 树 的形式。
自定义模块的 每个文件夹中 需要包含一个 空 __init__.py
文件,用来让 Python 识别出这是一个包。示例:
将项目进行模块化拆分,其 好处 包括:
- 使得整个项目的逻辑更加清晰,方便很多人一起开发,以及对项目进行增删查改;
- 方便模块之间进行相互调用
3.2、模块和包的使用 (from import)
假设某项目结构如下图所示,现在需要在 main.py 下调用模块文件中的 变量、函数 等。
module1.py 中的代码:
name = "miyazaki"def greet():print("%s says: hello world!" % name)
module2.py中的代码:
age = 18class Speak:def __init__(self, age1 = 20):self.age1 = age1def speak_chinese(self):print("我今年 %d 岁" % self.age1)
方法一:from 模块 import 变量/函数/类
格式:from module import var,func,cls
注意:导入 模块名 和 当前的 py 文件 必须在 同一级目录
例如:实现在 main.py 中调用 module2 模块中的内容
from module2 import age, Speakprint(age)man = Speak()
man.speak_chinese()
"""output
18
我今年 20 岁"""
方式二:from 模块 import 变量名 as 其他变量名
格式:from module import var as other_var
例如: 要求 main.py 中存在有与 module2 相同的变量名,要求同时使用 2 个变量名
from module2 import age as m2_ageage = 20print(age, m2_age)
"""output
20 18"""
方式三:from 包.模块 import 变量/函数/类
格式:from pkg.module import var,func,cls
例如:实现在 main.py 中调用 module1 模块中的内容
from dir.module1 import name, greetprint(name)
greet()
"""output
miyazaki
miyazaki says: hello world!"""
方式四:from 包 import 模块
格式:from pkg import module
注意:调用 模块 中的 变量、函数和类名 时,要用 模块名.变量
或者 模块名.函数
或者 模块名.类名
的方式来调用
例如:实现在 main.py 中调用 module1 模块中的内容
from dir import module1print(module1.name)
module1.greet()
"""output
miyazaki
miyazaki says: hello world!"""
方式五:import 变量/函数/类
格式:import var,func,cls
注意:python 的 内置模块 可以使用这种方式,也可以用 from module import var,func,cls
方式来进行代替
例如:实现在 main.py 中调用 内置模块 time 中的内容
import time
time.sleep(2)from time import sleep
sleep(2)
3.3、import 和 from…import 的区别
import
和 from import
都是用来 引入其他模块或包 的关键字。它们之间的区别在于 引入的方式 和 作用范围。
- import:使用
import
关键字可以 引入 整个模块或包,并且在 使用 其中的 函数、类或变量 时 需要 通过模块名来访问。例如:import module_name
,然后使用module_name.function_name()
来访问模块中的函数。 - from import:使用
from import
关键字可以从模块或包中直接 引入 特定的函数、类或变量,而 不需要 通过模块名来访问。例如:from module_name import function_name
,然后直接使用function_name()
来访问函数。
推荐使用:import 模块名,然后再 模块名.xxx来调用的形式。from xxx import * 这种写法,会给你带来无穷无尽的噩梦。
3.4、包的管理 (通过命令行)
写项目时,不会所有代码都自己实现,会用到很多网络上现成的 包 (模块)。
以安装 pygame
这个包为例:
- 安装包:
pip3 install pygame --user
- 升级包:
pip3 install pygame --user --upgrade
- 删除包:
pip3 uninstall pygame