类方法
定义格式:
@classmethod
def 方法名(cls,…):
pass
调用格式:
类对象.类方法名
注意:
在类方法中,不能使用self
但是可以使用 cls,该参数用来表示 当前类对象,这个参数也是自动传递的\
应用场景:
一般在设计类时,如果有类方法,该类一般不会去实例对象,直接使用类对象来操作(比如:数学函数类)
一役用来定义工具类使用
Math.max(1,2)
'''类方法'''
class MyMath(object):
# 定义一个类属性
n = 999
# 标准格式
@classmethod # 这是一个装饰 器,用来表示下面的方法是一个类方法
def sum(cls,*args):
print(cls.n)
m = 0
for i in args:
m += i
return m
# @classmethod 是一个装饰 器,用来修饰一个方法成为类方法,当在执行该 类方法时,解释 会自动 将类对象传递到参数 cls中
@classmethod
def show(cls):
print('show class method')
# 执行类方法
# print(MyMath.sum(1,2,3,4,5))
#
#
# mm = MyMath()
# print(mm.sum(1, 2, 3, 4, 5))
MyMath.show()
静态方法
格式:
@staticmethod
def 方法名(参数列表…):
pass
调用方式:
同类方法
类对象.静态方法名()
设计目的:
静态方法实际上就是放到类当中的一堆普通函数
作用:
静态方法同类方法相似,也是在不需要实例对象产生的条件下,可以使用静态方法来实现
一般这两种方法,都是用在工具类的实现上.
通过类,将一系列的功能方法进行整合到一起.
实例方法,必须通过实例对象调用执行,(第一个参数是当前调用该方法的实例)
类方法, 当不需要产生实例对象时,可以使用类方法来实现相应的代码功能,类方法可以直接
使用类对象来调用,类方法的第一个参数是 cls,用来接收当前类对象,通过个参数,
可以各个类方法中进行共享数据
静态方法, 作用同类方法相似,但是静态方法不接收任何默认参数(实例对象或类对象),静态方法
其实就是将一些相关联的普通方法使用类进行整合.
类方法和静态方法,一般在使用时,大多数用来实现工具类.
'''
静态方法
'''
# 设计 一个编码工具类
class EncodeUtil(object):
n = 1
# 编码方法
@staticmethod
def encode_data(data, format):
print(f'对数据 {data} 使用 {format} 格式 进行了编码')
# 解码方法
@staticmethod
def decode_data(data, format):
print(EncodeUtil.n)
print(f'对数据 {data} 使用 {format} 格式 进行了解编码')
# 测试
# eu = EncodeUtil()
# eu.encode_data('hello','utf-8')
EncodeUtil.encode_data('Hello','utf-8')
EncodeUtil.decode_data("hello",'GBK')
1. 从类方法和实例方法以及静态方法的定义形式就可以看出来,类方法的第一个参数是类对象cls,那么通过cls引用的必定是类对象的属性和方法;
2.实例方法的第一个参数是实例对象self,那么通过self引用的可能是类属性、也有可能是实例属性(这个需要具体分析),不过在存在相同名称的类属性和实例属性的情况下,实例属性优先级更高。
3.静态方法中不需要额外定义参数,因此在静态方法中引用类属性的话,必须通过类实例对象来引
1. 模块介绍
在Python中,一个.py文件就是一个模块
在Python,万物皆对象,模块也不例外
通过模块,可以有效的组织代码结构,让代码结构更加清晰
但是,初期可能让大家逻辑上更加混乱
2. 导入模块
导入模块是指:
在一个.py文件中,使用另外一个.py文件时,需要将这个文件导入
在一个模块中,使用另外一个模块时,需要将这个模块导入
方式一:
import 模块名 (掌握)
方式二:
from 模块名 import 成员名 (掌握)
特例:
from 模块名 import * (掌握)
别名:
import 模块名 as 别名
from 模块名 import 成员名 as 成员别名
两种导入方式区别:
1.import方式,是拿到了模块对象的引用地址,通过这个地址来使用模块中的成员
2.from-import方式,相当于将被导入模块中的成员,复制了一份到本地模块中.所以可以直接使用成员来访问被导入的成员
3.对于 import 方式来说,没有任何限制
4.对于from-import方式来说,有些成员是不能被导入的(有权限限制)
import os
import time
import random
import sys
import functools
# 方式一
# import p_05模块
#
# # 使用时,需要使用模块对象.成员
# print(p_05模块.n)
#
# p_05模块.show()
#
# tom = p_05模块.Cat()
# tom.show()
# 方式一的别名形式
# 别名就是为复杂的模块名起一个代号
# 可以通过这个代号 来调用 模块中的相应的成员
# import p_05模块 as p5m
# print(p5m.n)
# p5m.show()
# p5m.Cat().show()
# p5m.Cat().show()
# 方式 二
# 导入指定模块中的指定成员
# from p_05模块 import n
# from p_05模块 import show
# from p_05模块 import Cat as CatClass
#
# # 当使用from-import 方式 导入 时,不需要再使用 模块名.成员 形式
# # 可以在当前文件中,直接 使用成员名,相当于将导入的成功复制到了本地一份
# print(n)
# show()
# CatClass().show()
# 这两种 方式 的区别
# 使用import时,可以将整个模块中的成员 都 导入 进来
# 使用 from-import 时,可以使用谁导入谁,更加节省资源
# 如果想使用 From-import 方式 ,也可以导入所有的成员
# 如果使用通配符 * 的方式 导入所有的成员,那么就不能使用 as 为成员起别名了
from p_05模块 import *
print(n)
show()
Cat().show()
导入模块时的问题
'''
两种导入 模块方式的区别
'''
# import p_06模块 as p6m
#
# print(p6m.x)
# print(p6m._y)
# print(p6m.__z)
# from p_06模块 import *
# print(x)
# 在使用这种 方式 导入 时,不会将私有的属性导入
# print(_y)
# print(__z)
# from -import 方式 的命令冲突问题
def x():
print('x Function')
from p_06模块 import *
# x = 1
print(x)
x()
3. __all__的作用
all 是一个魔法属性,类型是一个列表,元素是字符串类型
作用:
可以改变在使用 from-import 方式导入模块时,成员的导入规则
'''
在模块中,定义三个变量
'''
# 通过 __all__ 这个魔法属性 可以改变from-import 的导入规则
# 一般不会在这里去使用 __all__ 属性
# __all__ = ['_y', '__z']
x = 1 # 全局变量,模块间的公有变量
_y = 2 # 私有变量,文件内私有变量
__z = 3 # 私有变量,一般出现在类中,不在直接 在模块中定义,这里只是借用
3.1 from-import
在导入时,会产生命名冲突问题
在程序中最后的定后会起作用
在这里插入代码片
4. 模块导入的搜索顺序(了解)
模块的分类:
1.自定义模块
2.系统模块
3.第三方模块
查找顺序:
1. 当前程序所在目录
2. 在当前程序所在工程的根目录
3. PYTHONPATH
4. 系统目录
5. site_packages 第三方模块的安装目录
name (掌握)
作用:
如果__name__ 出现在当前执行的模块中时,得到的值是 main 这个字符串,用来表示执行的是当前文件
如果__name__ 出现在在了被导入模块中时,得到的值是被导入模块的模块名
第一个文件
n = 1
def show():
print('show')
class Cat(object):
def show(self):
print('Cat_show')
# 在当前文件下测试成员的使用
# 当使用 __name__ 属性在获取当前模块名时,会有两种 效果
# 如果当前模块文件是 主动执行 时,__name__ 得到的结果是字符串 __main__ 表示这是程序的入口
# 如果当前模块文件是 被动执行 时(被别人导入时),__name__ 得到的结果就是当前模块文件的文件名
print('name:', __name__)
if __name__ == '__main__':
print(n)
show()
Cat().show()
第二个文件
'''
使用模块
'''
import p_08模块
print(__name__)
# 通过这个判断 来做为程序的程序 入口
if __name__ == '__main__':
print('程序 的入口')
print(p_08模块.n)
5. 包
包:就是一个文件夹
区别:
在python3以前,包中是有一个文件 __init__.py ,没有该文件的就是一个普通 的文件夹,有该文件才是包
在python3以后,不管有没有,都认为是一个包
'''
导入包中的模块
'''
# 导入 normal_dir 这个包中的 a 模块
# import normal_dir.a
# print(normal_dir.a.m)
# import normal_dir.a as nda
# print(nda.m)
# 使用from-import 方式导入
# 从 normal_pack 包中导入 b 模块
# 使用时,需要指定包名. 成员
# from normal_pack import b
# print(b.n)
# 从 normal_pack的 b 模块中,导入 b 模块中的所有成员
from normal_pack.b import *
print(n)
6. 导入包中的模块
6. 导入包中的模块
方式一:
通过包和模块的路径,明确的告诉解释器,要导入哪个包里的哪个模块
import 包名.模块名
from 包名 import 模块名
from 包名.模块名 import 成员名
方式二:
import 包名
from 包名 import *
在导入时,不会指定模块名,只指定包名
这时,默认情况下(__init__.py 为空)哪个模块都不会导入
为了能让模块正常导入,这里需要 __init__.py 文件中设置可以被导入的模块
通过方式:
from . import 模块名
注意:
__all__ 只对 from 包名 import * 方法生效,对 import 包名 方式无效
__all__ 在 __init__.py 文件中的使用了解即可
如果包有很多层级的情况:
www.itcast.cn
cn
itcast
python
java
c++
from cn.itcast.python import database
www.itcast.cn
cn
itcast
web
a.py
b.py
c.py
spider
a.py
b.py
c.py
'''
导入包中的模块
'''
# 导入 normal_dir 这个包中的 a 模块
# import normal_dir.a
# print(normal_dir.a.m)
# import normal_dir.a as nda
# print(nda.m)
# 使用from-import 方式导入
# 从 normal_pack 包中导入 b 模块
# 使用时,需要指定包名. 成员
# from normal_pack import b
# print(b.n)
# 从 normal_pack的 b 模块中,导入 b 模块中的所有成员
from normal_pack.b import *
print(n)
模块和包的小结
小结模块导入:
1. 导入模块:
两种方式
import 包名.模块名 -> 包名.模块名.成员
from 包名.模块名 import 成员名 -> 直接使用成员
from 包名 import 模块名 -> 模块名.成员
from 包名.模块名 import * -> 直接使用成员
2. __all__ 这个魔法属性,会影响 from - import * 这种导入方式的模块
在all 中指定的模块或成员会被导入,没有指定的不会被导入
3. 了解模块导入时的搜索路径
sys模块中的path变量中保存了搜索路径
a. 当前程序所在同级目录
b. 当前程序所在工程的根目录
c. PYTHONPATH 环境变量中设置的目录
d. 系统目录
e. site-packages 这个第三方模块安装目录
4. 包
包就是一个文件夹
包和普通文件夹的功能在于 包中有一个 __init__.py 文件
该文件的作用是在只导入包时,指定可以导入的模块有哪些
如果这个文件是空的,那么在导入这个包时,不会导入任何模块
在指定可以导入的模块时, 可以使用 from . import 可导入模块名
init_py文件的作用
# import cn.itcast.web.a as weba1
# print(weba1.m)
#
# from cn.itcast.web import a as weba2
# print(weba2.m)
#
# from cn.itcast.web.a import *
# print(m)
# 想直接导入这个 web 包
# 在这里,如果只导到包的位置,那么通过 这个包去找模块时,会报错,因为不确定要导入哪个模块
# 需要在包中的 __init__.py 中,告诉解释器,当导入包时,应该导入哪些模块
# import cn.itcast.web as web
# print(web.a.m)
# print(web.b.n)
# from cn.itcast import web
# print(web.a.m)
# print(web.b.n)
# 小结:
'''
当在使用 import 方式 ,或from-import 方式 导入包时,
需要在 __init__.py 文件中,明确的指出可以被导入的模块有哪些
使用 from . import 模块名 形式指定
如果在该 文件中没有指定 可以导入的模块时,默认不导入任何模块
'''
import cn.itcast.web as web
print(web.a.m)
from cn.itcast.web import *
print(a.m)
print(b.n)