调用自己写的模块
首先在同一目录下创建两个py文件,比如我一个名字为Demo.py一个为Test.py文件
Test.py代码:
print('我是Test.py')
def Getstr():
print('我是Getstr方法')
如果我想在Demo中调用Test该怎么办呢?(可能你大概已经猜到)
Demo代码:
import Test
#运行会输出:我是Test.py
可以看到调用Test模块就会执行输出我是Test.py
那如果我多次导入会不会多次输出呢?答案显然不是
因为当我们导入模块的时候,会在内存中(sys.modules)查找是否有这个模块,存在不添加,不存在添加。
注意:我们导入模块时,会现在本地文件中查找该模块,再去系统变量中查找也就是说如果我们将本地py文件的命名修改成上篇文章的任意一个,再去使用它就会报错。
如果我想要调用Test中的Getstr方法呢?
Demo代码:
import Test
Test.Getstr()即可。
输出:我是Test.py
我是Getstr方法
给模块起别名:as
为什么起别名?模块名字很长?怎么可能。例如
import Test as t
我们想一个问题,如果两个模块都拥有同一个方法。
我们可不可以给一个相同的别名?
如上我们发现我们每次调用Test的方法或者参数,都会使用Demo.xxx
可以不可以直接调用方法呢?
例如:from Test import Getstr 或者from Test import * # *:表示所有
#调用Getstr方法
Getstr()
对于*(只针对*):
当我们导入Test下的所有方法和变量时如果我不想给Demo用该怎么办?
我们可以在Test.py文件中添加:
__all__=['Getstr']
def Getstr2():
print('我是Getstr2')
此时,在Demo中调用Getstr2()就会报错,不给他用。
如果想给他用加上就好:
__all__=['Getstr','Getstr2']
导入的另一种方式:.
我们经常看见 from xxx.xxx.xxx import xxx
.的左边必须是包,也就是文件夹,导入其他文件夹下的py文件,import后不能有点
同时也可以一次导入多个:
from Test import Getstr,Getstr2
以上我们还发现每次调用Test的时候都会输出我是Test.py
如果我们想只执行Test的时候执行'我是Test.py'这句话,而在其他文件调用的时候不执行怎么办?
只需要将print('我是Test.py')删除写成这样:
if __name__ == '__main__':
print('我是Test.py')
可以猜到这个if判断就是判断是否执行的当前文件吧。
__init__文件:
我们使用pycharm软件创建一个包时都会有一个__init__文件,当我们只导入包的时候,会执行__init__文件,和上面的一个道理也就是说我们导入包和导入模块的时候,都会有一个相当于加载事件,当调用的时候就会执行。
异常处理
#try: 可能出现错误的代码
#except:当发生错误执行的代码,可以写多个except,根据错误类型执行代码,也可以捕捉所有错误,并提示
例如:
try:
int('qwe')
except Exception:
print('出现错误')
else:
print('1111')
finally:
print('12345645498')
Exception:是捕捉所有的错误。
else:是没有报错的时候执行
finally:不管报错不报错都执行的代码
其他错误:
BaseException:所有异常的基类
SystemExit:解释器请求退出
KeyboardInterrupt:用户中断执行(通常是输入^C)
Exception:常规错误的基类
StopIteration:迭代器没有更多的值
GeneratorExit:生成器(generator)发生异常来通知退出
SystemExit:Python 解释器请求退出
StandardError:所有的内建标准异常的基类
ArithmeticError:所有数值计算错误的基类
FloatingPointError:浮点计算错误
OverflowError:数值运算超出最大限制
ZeroDivisionError:除(或取模)零 (所有数据类型)
AssertionError:断言语句失败
AttributeError:对象没有这个属性
EOFError:没有内建输入,到达EOF 标记
EnvironmentError:操作系统错误的基类
IOError:输入/输出操作失败
OSError:操作系统错误
WindowsError:系统调用失败
ImportError:导入模块/对象失败
KeyboardInterrupt:用户中断执行(通常是输入^C)
LookupError:无效数据查询的基类
IndexError:序列中没有没有此索引(index)
KeyError:映射中没有这个键
MemoryError:内存溢出错误(对于Python 解释器不是致命的)
NameError:未声明/初始化对象 (没有属性)
UnboundLocalError:访问未初始化的本地变量
ReferenceError:弱引用(Weak reference)试图访问已经垃圾回收了的对象
RuntimeError:一般的运行时错误
NotImplementedError:尚未实现的方法
SyntaxError:Python语法错误
IndentationError:缩进错误
TabError:Tab和空格混用
SystemError:一般的解释器系统错误
TypeError:对类型无效的操作
ValueError:传入无效的参数
UnicodeError:Unicode 相关的错误
UnicodeDecodeError:Unicode 解码时的错误
UnicodeEncodeError:Unicode 编码时错误
UnicodeTranslateError:Unicode 转换时错误
Warning:警告的基类
DeprecationWarning:关于被弃用的特征的警告
FutureWarning:关于构造将来语义会有改变的警告
OverflowWarning:旧的关于自动提升为长整型(long)的警告
PendingDeprecationWarning:关于特性将会被废弃的警告
RuntimeWarning:可疑的运行时行为(runtime behavior)的警告
SyntaxWarning:可疑的语法的警告
UserWarning:用户代码生成的警告
面向对象
定义一个类
class Person:
gamename = '人类'
def __init__(self,*args):
print('正在定义属性。。。')
self.name = args[0]
self.age = args[1]
self.sex = args[2]
def Getwrite(self):
print(self.name,self.age,self.sex)
person = Person('张三',18,'男') # 实例化
person.Getwrite() # 张三 18 男
print(person.name) # 张三
print(person.__dict__) # {'name': '张三', 'age': 18, 'sex': '男'} 返回的是一个字典,你也可以这样person.__dict__['name']
Person:类名,可以自己定义
gamename:静态属性,不会改变 但是调用用类名调用
__init__:当实例化Person 会执行的函数 #实例化就会输出:正在定义属性。。。
self: self变量,可以看作包含所有属性的字典
*args:参数
实例化的参数会在__init__中接收
类是抽象的,他只负责定义一些属性和功能,经过实例化之后变成对象。
反过来 import 一个模块的过程就是一个实例化的过程
另:类是可以当作一个属性传入到另一个类中的。
面向对象之封装,继承,多态
继承:#为什么继承?提高代码的精简度,把公共的部分写在父类中,子类继承即可。
class Father:
pass
class Mother:
pass
# 单继承
class Son(Father):
pass
# 多继承 python特有的
class Daughter(Father,Mother):
pass
如上:Son类继承Father类,Daughter类继承Father类和mother类。
我们把Father,Mother叫父类或基类或超类
Son,Daughter类叫做子类或派生类
查看该类的父类:__base__
例如查看Son的父类:
print(Son.__base__)
print(Father.__base__) # 所有没有继承的类继承object类
当我们想要的子类中有和父类想相同的方法既要调用自己的方法,也要执行父类的方法需要用到super
实例:
class Father:
def GetName(self):
print('我是Father类的GetName方法')
class Son(Father):
def GetName(self):
print('我是Son类的GetName方法')
s = Son()
s.GetName()
如上只会输出:我是Son类的GetName方法
如果两个都想输出可以这样:
class Father:
def GetName(self):
print('我是Father类的GetName方法')
class Son(Father):
def GetName(self):
super().GetName()
print('我是Son类的GetName方法')
Def GetAge(self):
print('18')
s = Son()
s.GetName()
就会输出:
我是Father类的GetName方法
我是Son类的GetName方法
当一个类多继承时候在python3中遵循广度优先的原则,在python2.7中遵守深度优先的原则
多态:
一个方法表现的不同形式:
class A:
def write(self):
print('A')
class B:
def write(self):
print('B')
class C:
def write(self):
print('C')
def test(obj):
obj.write()
a = A()
b = B()
c = C()
test(a)
test(b)
test(c)
输出 A B C
封装:
封装,顾名思义就是将内容封装到某个地方,以后再去调用被封装在某处的内容。
对于面向对象的封装来说,其实就是使用构造方法将内容封装到 对象 中,然后通过对象直接或者self间接获取被封装的内容。
class Getstr:
def __init__(self,name,age):
self.name = name
self.age = age
def Getname(self):
print('我的名字是:%s'%self.name)
def GetAge(self):
print('我的年龄是:%s'%self.age)
s = Getstr('张三',18)
s.GetName()
s.GetAge()
输出:
我的名字是:张三
我的年龄是:18