续上上篇的讲解:【备战测开】—— 编程语言Python(一)
6 面向对象编程
所谓的面向对象其实就是把属性和方法封装起来,以供重复调用
6.1 类和对象
参考博客:python类和对象最全详解(持续修订中)
class Person:
def __init__(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex
def sing(self):
print(f"{self.name}唱的真好听")
def dump(self):
print(f"{self.name}跳的真不错")
def rap(self):
print(f"{self.name}世界第一")
shuaishuai = Person("帅帅",18,"superman")
对象:实际生活中具体的事物
类:封装对象的属性和行为的载体
总结:类是对象的抽象,对象是类的具体实例
__init__
:第一个参数必须是self,代表当前对象,然后第二个参数开始就随意,但是这些参数在创建对象的时候必须一一实现
命名空间:类空间和对象空间
类也遵从自上而上执行,所以如果类里面有同名的方法,前一个方法会被后一个方法覆盖
# 创建一个类,能够自动统计当前类创建了多少个对象
class Person():
num = 0
def __init__(self):
Person.num += 1
print(Person.num)
Person()
Person()
Person()
Person()
print(Person.num)
常见的内置方法
常用的内置方法:
__init__:
1.用来构造初始化函数,用来给对象进行初始化属性,所以不需要返回值
2.创建对象的时候自动调用
3.自定义类如果不定义的话,默认调用父类object的,同理继承也是,子类若无,调用父类的,若有,调用自己的
class Animal:
def __init__(self):
print("init初始化方法,没有调用父类object")
Animal()
#结果:
init初始化方法,没有调用父类object
__new__:
1.用所给类创建一个对象,并且返回这个对象
2.因为是给类创建实例,所以至少传一个参数cls,参数cls代表代表要实例化的类,此参数在实例化时用python解释器自动提供
3.在类实例化时内部创建类实例的函数,并且返回这个实例,所以它是实例时最先被调用的方法,一般不要人为定义该方法
4.因为要创建实例返回实例,所以要有返回值。return父类__new__出来的实例,或者直接是object的__new__出来的实例
__class__
__delattr__
__dict__
__dir__
__doc__
__eq__
__format__
__ge__
__getattribute__
__gt__
__hash__
__init__
__init_subclass__
__le__
__lt__
__module__
__ne__
__new__
__reduce__
__reduce_ex__
__repr__
__setattr__
__sizeof__
__str__
__subclasshook__
__weakref__
类的成员主要有属性和方法,属性可以随意,方法的第一个参数必须是self
访问限制:可以使用单下划线,双下划线,首尾双下划线来限制访问权限
单下划线开头的是protected类型的成员,只允许类本身和子类进行访问,不能使用from xxx import ccc进行导入,双下划线只能由定义了该属性或方法的类调用,而不能由类的对象调用,类的对象如果想调用,必须使用set/get方法
class Person:
def __init__(self, name,sex):
self.name = name
self.__age = None
self.sex = sex
def set(self,age):
self.__age = age
def get(self):
return self.__age
def sing(self):
print(f"{self.name}唱的真好听")
def dump(self):
print(f"{self.name}跳的真不错")
def rap(self):
print(f"{self.name}世界第一")
shuaishuai = Person("帅帅","superman") # 初始化
#这个时候初始化帅帅的年龄就会报错,可以使用set方法来赋值,get方法取值
shuaishuai.set(18)
print(shuaishuai.get())
属性
(1)创建用于计算的属性
python中使用@property
将一个方法转换为属性,从而实现用于计算的属性,将方法转换为属性后,可以直接通过方法名来访问,而不需要加括号,@property
可以将属性设置为只读属性
class Person:
def __init__(self,name,age):
self.name = name
self.age = age
@property
def func(self):
if self.age < 150 and self.age > 0:
print(self.age)
else:
print("想啥呢?")
shuaishuai = Person("帅帅",18)
shuaishuai.func #func这个属性不能对其赋值,因为他本质也是一个函数
(2)为属性添加安全保护机制
python中有了私有属性和私有方法供大家使用。私有属性就是在属性前面加两个下划线,然后给这个私有属性给予set和get方法,这样对象调用的时候就只能通过set方法来进行赋值,get方法来获取值
class Person:
def __init__(self, name, sex):
self.name = name
self.__age = None
self.sex = sex
def set(self, age):
self.__age = age
def get(self):
return self.__age
类与类之间的关系
有三种关系:
- 依赖(关联)
帅帅玩电脑,电脑需要帅帅玩
class Person:
def run(self):
print("我没事干")
class Computer:
def play(self, tool):
tool.run()
print("我是电脑,玩我")
class Phone:
def play(self,tool):
tool.run()
print("我有王者荣耀,来玩啊")
shuaishuai = Person()
dnf = Computer()
dnf.play(shuaishuai) #依赖是给一个类的对象的方法给另一个对象
wangzhe = Phone()
wangzhe.play(shuaishuai)
- 组合(聚合):一个类需要某个类的具体对象去做一些事情,这就是组合。轮胎和发动机组合成了车一样。
class Car:
def __init__(self,name,power = None):
self.__name = name
self.__power = power
def set_power(self,power):
self.__power = power
def zhuang_Tread(self):
print(f"{self.__name}装好了{self.__power.get_name()}的轮胎")
def saiche_power(self):
print(f"{self.__name}装好了{self.__power.get_name()}的发动机")
class Tread:
def __init__(self,name):
self.__name = name
def set_name(self,name):
self.__name = name
def get_name(self):
return self.__name
class Engine:
def __init__(self,name):
self.__name = name
def set_name(self,name):
self.__name = name
def get_name(self):
return self.__name
tread = Tread("牛逼牌")
engine = Engine("赛车")
car = Car("奔驰",tread)
car.zhuang_Tread()
car.set_power(engine)
car.saiche_power()
- 继承(实现)
#固定结构:
#父类
class Person(object): #括号里面写要继承的类
def __init__(self, name,sex):
self.name = name
self.__age = None
self.sex = sex
def set(self,age):
self.__age = age
def get(self):
return self.__age
def sing(self):
print(f"{self.name}唱的真好听")
def dump(self):
print(f"{self.name}跳的真不错")
def rap(self):
print(f"{self.name}世界第一")
#子类
class Boy(Person):
pass
shuaishuai = Boy("帅帅","superman")
shuaishuai.sing()
#结论:
可以看出,子类Boy什么都没有写,只是继承了一下父类Person,他就拥有了父类的属性和方法,但是私有属性没有被继承。
方法重写
class Person(object):
def __init__(self, name):
self.name = name
def sing(self):
print(f"{self.name}唱的真好听")
#子类
class Boy(Person):
def sing(self):
print(f"{self.name}最帅")
shuaishuai = Boy("帅帅")
shuaishuai.sing()
#结果:帅帅最帅
这个时候我们可以发现,原来我们不重写sing方法的时候,他调用的是父类的sing方法,当我们在子类中进行重写之后,他显示的就是子类的方法。
由此可以得出查找顺序:对象调用某个属性或者方法的时候,会先在当前类中进行查找,如果找不到,就去他的父类对象今进行查找。
多继承和多重继承的区别
- 多继承是子类不断的继承父类,依次类推,最后的孙子类拥有父类跟子类的方法
#多继承
class Person(object):
def run(self):
print("人会跑")
class Boy(Person):
def like_girl(self):
print("男孩喜欢女孩子")
class Girl(Boy):
def like_boy(self):
print("女孩子也喜欢男孩子")
class Kid(Girl):
def kids(self):
print("孩子是男孩跟女孩的爱情结晶")
kid = Kid()
kid.run()
kid.like_girl()
kid.like_boy()
kid.kids()
#结果
人会跑
男孩喜欢女孩子
女孩子也喜欢男孩子
孩子是男孩跟女孩的爱情结晶
- 多重继承:一个类可以从Python中的多个基类派生
class Base1:
pass
class Base2:
pass
class MultiDerived(Base1, Base2):
pass
6.2 三大特性
6.2.1 封装
封装就是把一个个的属性和方法隐藏起来,只留下具体的接口供下一个人使用
私有属性:在属性前面加get/set方法,然后再当前类中进行调用和实现,外界只能使用这个属性的set/get方法来操作他。而且不能被子类继承
私有方法:在方法前面加两个下划线
破解私有属性:在名称前加上 _类名,即 _类名__名称(例如a._A__N)
其实加双下划线仅仅是一种变形操作
类中所有双下划线开头的名称如__x都会自动变形成:_类名__x的形式
6.2.2 继承
#固定结构:
#父类
class Person(object): #括号里面写要继承的类
def __init__(self, name,sex):
self.name = name
self.__age = None
self.sex = sex
def set(self,age):
self.__age = age
def get(self):
return self.__age
def sing(self):
print(f"{self.name}唱的真好听")
def dump(self):
print(f"{self.name}跳的真不错")
def rap(self):
print(f"{self.name}世界第一")
#子类
class Boy(Person):
pass
shuaishuai = Boy("帅帅","superman")
shuaishuai.sing()
#结论:
可以看出,子类Boy什么都没有写,只是继承了一下父类Person,他就拥有了父类的属性和方法,但是私有属性没有被继承。
方法重写
class Person(object):
def __init__(self, name):
self.name = name
def sing(self):
print(f"{self.name}唱的真好听")
#子类
class Boy(Person):
def sing(self):
print(f"{self.name}最帅")
shuaishuai = Boy("帅帅")
shuaishuai.sing()
#结果:帅帅最帅
这个时候我们可以发现,原来我们不重写sing方法的时候,他调用的是父类的sing方法,当我们在子类中进行重写之后,他显示的就是子类的方法。
由此可以得出查找顺序:对象调用某个属性或者方法的时候,会先在当前类中进行查找,如果找不到,就去他的父类对象今进行查找。
多继承和多重继承的区别
- 多继承是子类不断的继承父类,依次类推,最后的孙子类拥有父类跟子类的方法
#多继承
class Person(object):
def run(self):
print("人会跑")
class Boy(Person):
def like_girl(self):
print("男孩喜欢女孩子")
class Girl(Boy):
def like_boy(self):
print("女孩子也喜欢男孩子")
class Kid(Girl):
def kids(self):
print("孩子是男孩跟女孩的爱情结晶")
kid = Kid()
kid.run()
kid.like_girl()
kid.like_boy()
kid.kids()
#结果
人会跑
男孩喜欢女孩子
女孩子也喜欢男孩子
孩子是男孩跟女孩的爱情结晶
- 多重继承:一个类可以从Python中的多个基类派生
class Base1:
pass
class Base2:
pass
class MultiDerived(Base1, Base2):
pass
6.2.3 多态
参考博客:python中对多态的理解
(1)多态
多态是指一类事物有多种形态,比如动物类,可以有猫,狗,猪等等。(一个抽象类有多个子类,因而多态的概念依赖于继承)
import abc
class Animal(metaclass=abc.ABCMeta): #同一类事物:动物
@abc.abstractmethod
def talk(self):
pass
class Cat(Animal): #动物的形态之一:猫
def talk(self):
print('say miaomiao')
class Dog(Animal): #动物的形态之二:狗
def talk(self):
print('say wangwang')
class Pig(Animal): #动物的形态之三:猪
def talk(self):
print('say aoao')
(2)多态性
多态性是指具有不同功能的函数可以使用相同的函数名,这样就可以用一个函数名调用不同内容的函数。在面向对象方法中一般是这样表述多态性:向不同的对象发送同一条消息,不同的对象在接收时会产生不同的行为(即方法)。也就是说,每个对象可以用自己的方式去响应共同的消息。所谓消息,就是调用函数,不同的行为就是指不同的实现,即执行不同的函数。
class Animal(object):
def talk(self):
pass
class Cat(Animal):
def talk(self):
print('miao miao')
class Dog(Animal):
def talk(self):
print('wang wang')
c = Cat()
d = Dog()
def fun(obj):
obj.talk()
fun(c)
fun(d)
多态性:一个接口,多种实现
好处:
(1)增加了程序的灵活性,以不变应万变,不论对象千变万化,使用者都是同一种形式去调用,如func(obj)
(2)增加了程序额可扩展性,通过继承animal类创建了一个新的类,使用者无需更改自己的代码,还是用func(obj)去调用
6.3 运算符重载
参考博客:
浅析Python运算符重载
Python 运算符重载
6.4 装饰器
我们调用一个带有返回值的函数 x,此时函数 x 为我们返回一个函数 y,这个函数 y 就被称作闭包
def x(id):
def y(name):
print ('id:', id, 'name:', name)
return y
y = x('ityard')
y('程序之间')
闭包与类有一些相似:
(1)都能实现数据的封装、方法的复用
(2)通过使用闭包可以避免使用全局变量,还能将函数与其所操作的数据关连起来
装饰器(decorator)也称装饰函数,是一种闭包的应用,其主要是用于某些函数需要拓展功能,但又不希望修改原函数,它就是语法糖,使用它可以简化代码、增强其可读性,当然装饰器不是必须要求被使用的,不使用也是可以的,Python 中装饰器通过
@
符号来进行标识。
装饰器可以基于函数实现也可基于类实现,其使用方式基本是固定的,看一下基本步骤:
- 定义装饰函数(类)
- 定义业务函数
- 在业务函数上添加
@装饰函数(类)名
1)基于函数
# 装饰函数
def funA(fun):
def funB(*args, **kw):
print('函数 ' + fun.__name__ + ' 开始执行')
fun(*args, **kw)
print('函数 ' + fun.__name__ + ' 执行完成')
return funB
@funA
# 业务函数
def funC(name):
print('Hello', name)
funC('Jhon')
装饰函数也是可以接受参数的
# 装饰函数
def funA(flag):
def funB(fun):
def funC(*args, **kw):
if flag == True:
print('==========')
elif flag == False:
print('----------')
fun(*args, **kw)
return funC
return funB
@funA(False)
# 业务函数
def funD(name):
print('Hello', name)
funD('Jhon')
2)基于类
class Test(object):
def __init__(self, func):
print('函数名是 %s ' % func.__name__)
self.__func = func
def __call__(self, *args, **kwargs):
self.__func()
@Test
def hello():
print('Hello...')
hello()
Python 装饰器的 @...
相当于将被装饰的函数(业务函数)作为参数传入装饰函数(类)。
6.5 反射
参考博客:【测试开发】python系列教程:python反射
定义:通过字符串操作对象的数据和方法
作用:使用反射可以让用户,通过输入字符串,调用对象中的数据或者方法
python反射的四个方法
hasattr():判断对象是否含有字符串对应的数据或者功能
getattr():根据字符串获取对应的变量名或者函数名
setattr():根据字符串给对象设置数据 (名称空间的名字)
delattr():根据字符串删除对象对应的数据 (名称空间中的名字)
user = User()
while True:
choose = input('>>>').strip()
if hasattr(user,choose):
func = getattr(user,choose)
func()
else:
print('输入错误。。。。')
class Dog():
name='123'
def printagename(self):
print('111')
# 1.获取类中的值
print(getattr(Dog,'name'))
# 2.获取类中的方法
print(getattr(Dog,'printagename'))
# 3.调用
a=Dog()
getattr(Dog,'printagename')(a)
# 4.获取对象中的方法
print(getattr(a,'name'))
class Dog():
name='123'
def printagename(self):
print('111')
# 1.获取类中的值
print(getattr(Dog,'name'))
#2.通过反射修改
setattr(Dog,'name','addddd')
#3.获取修改后结果
print(getattr(Dog,'name'))
class Dog():
name='123'
def printagename(self):
print('111')
# 1.获取类中的值
print(getattr(Dog,'name'))
#2.通过反射删除
delattr(Dog,'name')
#3.获取修改后结果
print(getattr(Dog,'name'))
考虑有这么一个场景:需要根据用户输入url的不同,
调用不同的函数,实现不同的操作,
也就是一个WEB框架的url路由功能。
路由功能是web框架里的核心功能之一,例如Django的urls。
class url:
def login():
print("这是一个登陆页面!")
def logout():
print("这是一个退出页面!")
def home():
print("这是网站主页面!")
def run():
inp = input("请输入您想访问页面的url: ").strip()
if inp == "login":
url.login()
elif inp == "logout":
url.logout()
elif inp == "home":
url.home()
else:
print("404")
if __name__ == '__main__':
run()
可以通过反射来实现
class url:
def login():
print("这是一个登陆页面!")
def logout():
print("这是一个退出页面!")
def home():
print("这是网站主页面!")
def run():
inp = input("请输入您想访问页面的url:").strip()
func = getattr(url, inp)
func()
if __name__ == '__main__':
run()
7 模块
参考博客:详解Python模块化——模块(Modules)和包(Packages)
模块是包含 Python 定义和语句的文件。以.py为后缀的文件名就是模块名称
在模块内,模块的名称可以用全局变量 __name__
表示(字符串)
fibo.py
# Fibonacci numbers module
def fib(n): # write Fibonacci series up to n
a, b = 0, 1
while a < n:
print(a, end=' ')
a, b = b, a+b
print()
def fib2(n): # return Fibonacci series up to n
result = []
a, b = 0, 1
while a < n:
result.append(a)
a, b = b, a+b
return result
fibo.py就是一个模块,fib、fib2是fibo模块中的函数
7.1 导入模块
①导入整个模块
import fibo
可使用下面的语法来使用其中任何一个函数:
fibo.fib(10) # 模块名+句点不可省略
②导入模块中的特定函数
from fibo import fib, fib2
fib(20)
③导入模块中的所有函数
from fibo import * # 这种方式会导入除可下划线 (__)开头的名称以外的所有函数
fib(20)
给导入的模块一个别名
import numpy as np
单独运行模块
可以在模块中添加以下代码,就可以既用作脚本,也可用作可导入模块:
if __name__ == "__main__":
import sys
fib(int(sys.argv[1]))
7.2 常用模块
参考博客:Python常用模块大全(总结)
7.2.1 文件处理
Python 的os
模块提供了各种操作系统的接口,这些接口主要是用来操作文件和目录
→ os.getcwd()
查看当前路径
import os
print(os.getcwd())
→ os.listdir(path)
返回指定目录下包含的文件和目录名列表
import os
print(os.listdir('D:/'))
→ os.path.abspath(path)
返回路径 path 的绝对路径
import os
# 当前路径(相对路径方式)
print(os.path.abspath('.'))
→ os.path.split(path)
将路径 path 拆分为目录和文件两部分,返回结果为元组类型
import os
print(os.path.split('E:/tmp.txt'))
→ os.path.join(path, *paths)
将一个或多个 path(文件或目录) 进行拼接
import os
print(os.path.join('E:/','a.txt'))
→ os.path.getmtime(path)
返回 path(文件或目录)的最后修改时间
import os
import datetime
print(datetime.datetime.utcfromtimestamp(os.path.getatime('E:/tmp.txt')))
→ os.path.exists(path)
判断 path(文件或目录)是否存在,存在返回 True,否则返回 False
import os
print(os.path.exists('E:/tmp.txt'))
→ os.path.isdir(path)
判断 path 是否为目录
import os
print(os.path.isdir('E:/'))
→ os.path.isfile(path)
判断 path 是否为文件
import os
print(os.path.isfile('E:/tmp.txt'))
→ os.path.getsize(path)
返回 path 的大小,以字节为单位,若 path 是目录则返回 0
import os
print(os.path.getsize('E:/'))
print(os.path.getsize('E:/'))
→ os.mkdir()
创建一个目录
import os
os.mkdir('E:/a')
→ os.makedirs()
创建多级目录
import os
os.makedirs('E:/test1/test2')
→ os.chdir(path)
将当前工作目录更改为 path
import os
print(os.getcwd())
os.chdir('/test')
print(os.getcwd())
→ os.system(command)
调用 shell 脚本
import os
print(os.system('ping www.baidu.com'))
7.2.2 日期时间
🍉 time 模块
localtime() 表示当前时间,返回类型为 struct_time 对象
import time
t = time.localtime()
print('t-->', t)
print('tm_year-->', t.tm_year)
print('tm_year-->', t[0])
常用函数:
import time
print(time.time())
print(time.gmtime())
print(time.localtime())
print(time.asctime(time.localtime()))
print(time.tzname)
# strftime 使用
print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()))
strftime 函数日期格式化符号说明如下所示:
🍉 datetime 模块
datatime 模块重新封装了 time 模块,提供了更多接口,变得更加直观和易于调用
(1)date 类
import datetime
import time
print(datetime.date.today())
print(datetime.date.fromtimestamp(time.time()))
print(datetime.date.min)
print(datetime.date.max)
实例方法和属性如下所示:
import datetime
td = datetime.date.today()
print(td.replace(year=1945, month=8, day=15))
print(td.timetuple())
print(td.weekday())
print(td.isoweekday())
print(td.isocalendar())
print(td.isoformat())
print(td.strftime('%Y %m %d %H:%M:%S %f'))
print(td.year)
print(td.month)
print(td.day)
(2)time 类
time 类表示由时、分、秒、微秒组成的时间,格式为:time(hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0)
实例方法和属性如下所示:
import datetime
t = datetime.time(10, 10, 10)
print(t.isoformat())
print(t.replace(hour=9, minute=9))
print(t.strftime('%I:%M:%S %p'))
print(t.hour)
print(t.minute)
print(t.second)
print(t.microsecond)
print(t.tzinfo)
(3)datetime 类
datetime 包括了 date 与 time 的所有信息,格式为:datetime(year, month, day, hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0)
类方法和属性如下所示:
import datetime
print(datetime.datetime.today())
print(datetime.datetime.now())
print(datetime.datetime.utcnow())
print(datetime.datetime.fromtimestamp(time.time()))
print(datetime.datetime.utcfromtimestamp(time.time()))
print(datetime.datetime.combine(datetime.date(2019, 12, 1), datetime.time(10, 10, 10)))
print(datetime.datetime.min)
print(datetime.datetime.max)
实例方法和属性如下所示:
import datetime
td = datetime.datetime.today()
print(td.date())
print(td.time())
print(td.replace(day=11, second=10))
print(td.weekday())
print(td.isoweekday())
print(td.isocalendar())
print(td.isoformat())
print(td.strftime('%Y-%m-%d %H:%M:%S .%f'))
print(td.year)
print(td.month)
print(td.month)
print(td.hour)
print(td.minute)
print(td.second)
print(td.microsecond)
print(td.tzinfo)
🍉 calendar 模块
calendar 模块提供了很多可以处理日历的函数
(1)常用函数
import calendar
calendar.setfirstweekday(1)
print(calendar.firstweekday())
print(calendar.isleap(2019))
print(calendar.leapdays(1945, 2019))
print(calendar.weekday(2019, 12, 1))
print(calendar.monthrange(2019, 12))
print(calendar.month(2019, 12))
print(calendar.prcal(2019))
(2)Calendar 类
Calendar 对象提供了一些日历数据格式化的方法,实例方法如下所示:
from calendar import Calendar
c = Calendar()
print(list(c.iterweekdays()))
for i in c.itermonthdates(2019, 12):
print(i)
(3)TextCalendar 类
TextCalendar 为 Calendar子类,用来生成纯文本日历。实例方法如下所示:
from calendar import TextCalendar
tc = TextCalendar()
print(tc.formatmonth(2019, 12))
print(tc.formatyear(2019))
(4)HTMLCalendar类
HTMLCalendar 类可以生成 HTML 日历。实例方法如下所示:
from calendar import HTMLCalendar
hc = HTMLCalendar()
print(hc.formatmonth(2019, 12))
print(hc.formatyear(2019))
print(hc.formatyearpage(2019))
7.2.3 sys模块
sys 模块主要负责与 Python 解释器进行交互,该模块提供了一系列用于控制 Python 运行环境的函数和变量
🍎 argv
返回传递给 Python 脚本的命令行参数列表
import sys
if __name__ == '__main__':
args = sys.argv
print(args)
print(args[1])
🍎 version
返回 Python 解释器的版本信息
🍎 winver
返回 Python 解释器主版号
🍎 platform
返回操作系统平台名称
🍎 path
返回模块的搜索路径列表
🍎 maxsize
返回支持的最大整数值
🍎 maxunicode
返回支持的最大 Unicode 值
🍎 copyright
返回 Python 版权信息
🍎 modules
以字典类型返回系统导入的模块
🍎 byteorder
返回本地字节规则的指示器
🍎 executable
返回 Python 解释器所在路径
import sys
#print(sys.version)
#print(sys.winver)
#print(sys.platform)
#print(sys.path)
#print(sys.maxsize)
#print(sys.maxunicode)
#print(sys.copyright)
#print(sys.modules)
print(sys.byteorder)
print(sys.executable)
🍎 stdout
标准输出
import sys
sys.stdout.write('Hi' + '\n')
print('Hi')
🍎 stdin
标准输入
import sys
s1 = input()
s2 = sys.stdin.readline()
print(s1)
print(s2)
🍎 exit()
退出当前程序
import sys
print('Hi')
sys.exit()
print('John')
🍎 getdefaultencoding()
返回当前默认字符串编码的名称
🍎 getrefcount(obj)
返回对象的引用计数
🍎 getrecursionlimit()
返回支持的递归深度
🍎 getsizeof(object[, default])
以字节为单位返回对象的大小
🍎 setswitchinterval(interval)
设置线程切换的时间间隔
🍎 getswitchinterval()
返回线程切换时间间隔
import sys
print(sys.getdefaultencoding())
print(sys.getrefcount('123456'))
print(sys.getrecursionlimit())
print(sys.getsizeof('abcde'))
sys.setswitchinterval(1)
print(sys.getswitchinterval())
8 包
参考博客:python导包的几种方法 自定义包的生成以及导入详解
8.1 导入包
🍉 import 常规导入,直接导入整个包的所有的功能函数
import time
time.time()
🍉 import多个导入,导入多个包的所有功能函数
import random, time
🍉 from … import …导入整个包的部分功能函数
from random import randint
from time import time, localtime
🍉 通过from … import * 这个也是直接导入包的所有功能。相当于import …
from time import *
8.2 生成包
🍉 在实际的应用中用得也是比较多的,我们自定义我们自己写的功能包
首先在任意路径创建一个文件夹,来放我们自定义的包的文件
创建在/home/xyh/test_package,下边是目录结构。要在另一个不相关的文件夹下的python应用中引用到我们自定义的包。就是在/home/xyh/test_package2/use_lucky_package.py中导入lucky_package.py这个包,测试直接import lucky_package.py或者直接from test_package import lucky_package.py是不行的
直接导入,出现程序运行错误提示信息
要想成功导入需要做的两步:
① 在test_package文件夹中创建__init__.py文件,里边什么都不需要编辑
② 在代码中把test_package的文件的路径加入到python解释器可以搜索到的路径列表中,这里就用到了python的包sys模块
下边是运行过一次的目录结构:pyc文件是py文件编译后生成的字节码文件,不需要自己创建,在你第一次成功导入包并运行成功之后会自动生成
lucky_package.py
#_*_coding:utf-8_*_
# 导入random模块,我们要制作的包要用
import random
# 定义自定义包模块的简单功能
def test():
print(random.randint(1,10))
return('hello world')
use_lucky_package.py
#_*_coding:utf-8_*_
import sys
# 动态添加test_package文件夹的路径,为了能让此文件夹下的
# 自定义包成功的导入
# 要根据你自己的实际包的模块来决定路径。
sys.path.append('../')
# 打印所有python解释器可以搜索到的所有路径
print(sys.path)
# 导入自定义包
from test_package.lucky_package import *
# 输出lucky_package中test函数的结果:
result = test()
print(result)
9 异常处理
🥝 错误
- 语法错误
- 逻辑错误
🥝 异常
即便 Python 程序的语法是正确的,在运行它的时候,也有可能发生错误,运行期检测到的错误被称为异常;大多数的异常都不会被程序处理,都以错误信息的形式展现
BaseException
+-- SystemExit
+-- KeyboardInterrupt
+-- GeneratorExit
+-- Exception
+-- StopIteration
+-- StopAsyncIteration
+-- ArithmeticError
| +-- FloatingPointError
| +-- OverflowError
| +-- ZeroDivisionError
+-- AssertionError
+-- AttributeError
+-- BufferError
+-- EOFError
+-- ImportError
| +-- ModuleNotFoundError
+-- LookupError
| +-- IndexError
| +-- KeyError
+-- MemoryError
+-- NameError
| +-- UnboundLocalError
+-- OSError
| +-- BlockingIOError
| +-- ChildProcessError
| +-- ConnectionError
| | +-- BrokenPipeError
| | +-- ConnectionAbortedError
| | +-- ConnectionRefusedError
| | +-- ConnectionResetError
| +-- FileExistsError
| +-- FileNotFoundError
| +-- InterruptedError
| +-- IsADirectoryError
| +-- NotADirectoryError
| +-- PermissionError
| +-- ProcessLookupError
| +-- TimeoutError
+-- ReferenceError
+-- RuntimeError
| +-- NotImplementedError
| +-- RecursionError
+-- SyntaxError
| +-- IndentationError
| +-- TabError
+-- SystemError
+-- TypeError
+-- ValueError
| +-- UnicodeError
| +-- UnicodeDecodeError
| +-- UnicodeEncodeError
| +-- UnicodeTranslateError
+-- Warning
+-- DeprecationWarning
+-- PendingDeprecationWarning
+-- RuntimeWarning
+-- SyntaxWarning
+-- UserWarning
+-- FutureWarning
+-- ImportWarning
+-- UnicodeWarning
+-- BytesWarning
+-- ResourceWarning
9.1 捕获异常
Python 程序捕捉异常使用 try/except 语句
#1、被除数为 0,未捕获异常
def getNum(n):
return 10 / n
print(getNum(0))
#输出结果:ZeroDivisionError: division by zero
#2、捕获异常
def getNum(n):
try:
return 10 / n
except IOError:
print('Error: IOError argument.')
except ZeroDivisionError:
print('Error: ZeroDivisionError argument.')
print(getNum(0))
'''
输出结果:
Error: ZeroDivisionError argument.
None
'''
try 语句的工作方式为:
- 首先,执行 try 子句 (在 try 和 except 关键字之间的部分)
- 如果没有异常发生, except 子句 在 try 语句执行完毕后就被忽略了
- 如果在 try 子句执行过程中发生了异常,那么该子句其余的部分就会被忽略
- 如果异常匹配于 except 关键字后面指定的异常类型,就执行对应的except子句,然后继续执行 try 语句之后的代码
- 如果发生了一个异常,在 except 子句中没有与之匹配的分支,它就会传递到上一级 try 语句中
- 如果最终仍找不到对应的处理语句,它就成为一个 未处理异常,终止程序运行,显示提示信息
9.2 try…else…finally结构
try/except 语句还可以带有一个 else、finally子句,示例如下:
def getNum(n):
try:
print('try --> ',10 / n)
except ZeroDivisionError:
print('except --> Error: ZeroDivisionError argument.')
else:
print('else -->')
finally:
print('finally -->')
'''
1、调用:getNum(0)
输出结果:
except --> Error: ZeroDivisionError argument.
finally -->
2、调用:getNum(1)
输出结果:
try --> 10.0
else -->
finally -->
'''
其中,else 子句只能出现在所有 except 子句之后,只有在没有出现异常时执行;finally 子句放在最后,无论是否出现异常都会执行
9.3 自定义异常
🍉 抛出异常
使用 raise 语句允许强制抛出一个指定的异常,要抛出的异常由 raise 的唯一参数标识,它必需是一个异常实例或异常类(继承自 Exception 的类),如:
raise NameError('HiThere')
🍉 自定义异常
正常来说,Python 提供的异常类型已经满足我们的使用了,但是有时候我们有定制性的需求,我们可以自定义异常类,继承自 Error 或 Exception 类就可以了,看个例子:
#自定义异常类 MyExc
class MyExc(Exception): #继承Exception类
def __init__(self, value):
self.value = value
def __str__(self):
if self.value == 0:
return '被除数不能为0'
#自定义方法
def getNum(n):
try:
if n == 0:
exc = MyExc(n)
print(exc)
else:
print(10 / n)
except:
pass
getNum(1)
getNum(0)
在这个自定义的异常例子中,当参数 n 不为 0 时,则正常,当 n 等于 0,则抛出异常,自定义异常在实际应用中很少用到,了解即可
10 文件操作
参考博客:Python文件读写详解(非常详细)
(1)打开文件
使用open()函数来打开文件。open()函数接受两个参数,第一个是文件名,第二个是打开文件的模式。常见的模式有:
- ‘r’: 只读模式,用于读取文件内容。
- ‘w’: 写入模式,用于写入文件内容。如果文件不存在,会创建一个新文件;如果文件已存在,会清空文件内容。
- ‘a’: 追加模式,用于在文件末尾添加内容。如果文件不存在,会创建一个新文件。
- ‘b’: 二进制模式,用于处理二进制文件,如图片、视频等。
# 以只读模式打开文件
file = open('example.txt', 'r')
# 以写入模式打开文件(如果文件不存在则创建)
file = open('example.txt', 'w')
# 以追加模式打开文件(如果文件不存在则创建)
file = open('example.txt', 'a')
# 以二进制模式打开文件
file = open('example.jpg', 'rb')
(2)读取文件内容
1 读取整个文件
with open('example.txt', 'r') as file:
content = file.read()
print(content)
2 逐行读取
使用readline()方法可以逐行读取文件的内容
with open('example.txt', 'r') as file:
line = file.readline()
while line:
print(line)
line = file.readline()
3 读取所有行
使用readlines()方法可以将文件的所有行读取到一个列表中
with open('example.txt', 'r') as file:
lines = file.readlines()
for line in lines:
print(line)
(3)写入文件内容
1 写入单行
with open('example.txt', 'w') as file:
file.write('Hello, World')
2 写入多行
使用writelines()方法可以将多行内容写入文件
lines = ['Line 1\n', 'Line 2\n', 'Line 3\n']
with open('example.txt', 'w') as file:
file.writelines(lines)
(4)文件迭代器
文件对象是可迭代的,因此我们可以使用for循环逐行读取文件内容
with open('example.txt', 'r') as file:
for line in file:
print(line)
(5)上下文管理器(Context Manager)
使用with语句打开文件,可以确保在文件使用完毕后自动关闭文件,避免资源泄漏
with open('example.txt', 'r') as file:
content = file.read()
print(content) # 文件自动关闭
(6)异常处理
在文件读写过程中,可能会出现异常,例如文件不存在或权限错误。因此,在操作文件时,最好使用异常处理来增强程序的健壮性
try:
with open('example.txt', 'r') as file:
content = file.read()
print(content)
except FileNotFoundError:
print('文件不存在!')
except PermissionError:
print('无权限访问文件!')
except Exception as e:
print(f'发生未知错误:{e}')
(7)关闭文件
虽然使用with语句可以确保文件被正确关闭,但在某些情况下,可能需要手动关闭文件
file = open('example.txt', 'r')
content = file.read()
print(content)
file.close() # 手动关闭文件
(8)二进制文件操作
with open('example.jpg', 'rb') as file:
data = file.read() # 对二进制数据进行操作
(9)文件定位
在文件读写中,有时候需要移动文件指针的位置,可以使用seek()方法
with open('example.txt', 'r') as file:
content = file.read(10) # 读取前10个字符
print(content)
file.seek(0) # 移动文件指针到文件开头
content = file.read(5) # 再次读取前5个字符
print(content)
以上详解了Python基础,不正之处望读者指教