08 Python-函数(一)(二)

news/2024/11/24 12:07:00/

文章目录

  • 1. 可变对象
  • 2.函数简介
  • 3. 函数的参数
    • 3.1 形参和实参
    • 3.2 函数的传递方式
    • 3.3 实参的类型
    • 3.4 不定长参数
    • 3.5 参数的解包
  • 4.函数的返回值
  • 5.档字符串
  • 6.函数的作用域
    • 6.1. 作用域(scope)
      • 6.1.1 全局作用域
      • 6.1.2 函数作用域
  • 7.递归函数
    • 7.1.递归式函数有2个条件
    • 7.2.递归经典练习
      • 7.2.1 任意正整数的阶乘 n!= n*(n-1)!= n*(n-1)*......* 2*1
      • 7.2.1 任意正整数的n次幂 n**m=n*[n**(m-1)]=n*........*n
      • 7.2.2 检查一个任意字符串是否是回文字符串。如果是就返回True 不是就返回False
      • 7.2.3 汉诺塔
  • 8.命名空间

1. 可变对象

  • 每个对象当中都保存了3个数据: id(标识) type(类型) value(值)
  • 可变对象是对象id 不变时,可以修改对象的Value值的对象
  • 如: 列表、集合、字典等是可变对象
  • 不可变对象: 常用的有 数值、字符串、元组
  • 通过变量来修改可变对象里面的value值时,不会改变变量指向的对象
  • 变量重新赋值时,即使value不变,对象也发生了改变(id发生变化)
  • 当可变对象赋值给另一个变量时,两个变量id、type和value都相同,修改其中一个value时,另一个value 也跟着修改,但当一个变量被重新赋值后,另一个变量还会保持不变
a = [1,2,3]
b = a
print("修改前:a=",a,type(a),id(a))
print("修改前:b=",b,type(b),id(b))
# 通过索引来修改列表
a[0] = 8
print("修改后:a=",a,type(a),id(a))
print("修改后:b=",b,type(b),id(b))
# 为变量重新赋值
a = (4,5,6)
print("修改后:a=",a,type(a),id(a))
print("修改后:b=",b,type(b),id(b))# 定义列表a ,将变量a 赋值给 变量b
# 修改前:a= [1, 2, 3] <class 'list'> 39476744
# 修改前:b= [1, 2, 3] <class 'list'> 39476744
# 修改变量 a[0] =8  ,变量a b id未变,仅列表[0]=8
# 修改后:a= [8, 2, 3] <class 'list'> 39476744
# 修改后:b= [8, 2, 3] <class 'list'> 39476744
# 变量a 重新被赋值 [4,5,6],则 a id、type 和 value都发生改变,但变量b id、type 和 value 未变
# 修改后:a= (4, 5, 6) <class 'tuple'> 39171344
# 修改后:b= [8, 2, 3] <class 'list'> 39476744

2.函数简介

  • 函数也是一个对象
  • 函数用来保存一些可执行的代码,并且可以在需要时,对这些语句进行多次调用
  • 函数中保存的代码不会立即执行,需要调用函数才会执行
  • 定义函数语法:
    • def 函数名([参数1,参数2,…]):
    • 	代码块
      
  • 调用函数: 函数名([参数1,参数2,…] )
  • 注意:
    • 函数名必须符合标识符的规范(可以包含字母、数字、下划线但是不能以数字开头)
    • print是函数对象
    • print()是调用函数
def fn():print("hello world!")result="我是函数返回值"return resultprint(fn)
print(fn())# <function fn at 0x00000000025876A8>
# hello world!
# 我是函数返回值

3. 函数的参数

3.1 形参和实参

  • 形参(形式参数):定义形参就相当于在函数内部声明了变量,但是并不是赋值
    • 定义函数时,可以在函数括号里定义多个形参,多个形参用逗号(,)隔开
  • 实参(实际参数):指定了形参,那么在调用函数时必须传递实参,实参将会赋值 给对应的形参,简单来说有一个形参就要有一个实参
  • 如果定义了形参,调用时必须传定对应数量的实参
def s1():print(1+2)def s2(a,b):print(a,'+',b,'=',a+b)s1()
# s2() # TypeError: s() missing 2 required positional arguments: 'a' and 'b'
s2(10000,6)

3.2 函数的传递方式

  • 定义形参时,可以为形参指定默认值。指定了默认值以后,如果用户传递了参数则默认值不会生效。如果用户没有传递,则默认值就会生效
    • 可以指定多个形参指定默认值
    • 形参指定默认值必须定义在最后,不能定义在其它没有默认值的前面
  • 位置参数:位置参数就是将对应位置的实参赋值给对应位置的形参
  • 关键字参数 : 关键字参数可以不按照形参定义的顺序去传递,而根据参数名进行传递
  • 混合使用位置参数和关键字参数的时候必须将位置参数写到关键字参数前面

案例分析:
response= requests(url,headers=headers) 为什么要用这样用?

因为函数参数的传递方式决定的,函数参数有两种:实参和形参,定义时用形参,调用函数时用实参,实参与形参一一对应。函数参数有两种传递方式,位置传参和关键字传参,这两种方式可以混合一起使用,但是,混合使用位置参数和关键字参数的时候必须将位置参数写到关键字参数前面,实际上,该函数是 get(url, params=None, **kwargs) ,其中实参url 是位置参数,headers=headers 是 不定长参数。

def fn(a = 5,b = 6,c =10):print('a =',a)print('b =',b)print('c =',c)
fn(1,2,3)
fn(1,2)
fn()def fn2(a ,b ,c ):print('a =',a)print('b =',b)print('c =',c)fn2(b=1,c=2,a=3)
fn(1,2,c=20) # 位置传参和关键字传参可以混合使用
# fn2(c=20,1,2) # SyntaxError: positional argument follows keyword argument
# fn(1,2,a=20) # TypeError: fn() got multiple values for argument 'a'

3.3 实参的类型

  • 实参能传递任意对象,甚至包括函数
  • 函数在调用的时候解析器是不会检查函数的类型
def fn(a):print('fn函数输出结果:a =', a)def fn2(a):print('fn2函数输出结果:a =', a, "type(a)=", type(a))fn2(123)				# fn2函数输出结果:a = 123 type(a)= <class 'int'>
fn2([1,2,3])			# fn2函数输出结果:a = [1, 2, 3] type(a)= <class 'list'>
fn2(True)				# fn2函数输出结果:a = True type(a)= <class 'bool'>
fn2("python")			# fn2函数输出结果:a = python type(a)= <class 'str'>
fn2(fn)					# fn2函数输出结果:a = <function fn at 0x000000000225E840> type(a)= <class 'function'>
fn2(fn(1))				
# fn函数输出结果:a = 1
# fn2函数输出结果:a = None type(a)= <class 'NoneType'>
  • 在函数中对形参重新赋值,不会影响其他的变量
  • 如果形参是一个可变对象,当我们修改对象的value值,会影响到所指向该对象的变量
def fn4(a, b, c):# 在函数中对形参重新赋值,不会影响其他的变量a = 20# a是一个列表 修改列表里面的元素 如果形参时一个可变对象,当我们修改对象(改对象的值)# 会影响到所指向该对象的变量b[0] = 10c = bprint('函数内:a =', a, "id(a)=", id(a))print('函数内:b =', b, "id(a)=", id(b))print('函数内:c =', c, "id(a)=", id(c))a = 10
b = [1, 2, 3]
c = [1, 2, 3]print('调用前:a =', a, "id(a)=", id(a))
print('调用前:b =', b, "id(a)=", id(b))
print('调用前:c =', c, "id(a)=", id(c))fn4(a, b, c)print('调用后:a =', a, "id(a)=", id(a))
print('调用后:b =', b, "id(a)=", id(b))
print('调用后:c =', c, "id(a)=", id(c))# 调用前:a = 10 id(a)= 495808256
# 调用前:b = [1, 2, 3] id(a)= 42575368
# 调用前:c = [1, 2, 3] id(a)= 42574920
# 函数内:a = 20 id(a)= 495808576
# 函数内:b = [10, 2, 3] id(a)= 42575368
# 函数内:c = [10, 2, 3] id(a)= 42575368
# 调用后:a = 10 id(a)= 495808256
# 调用后:b = [10, 2, 3] id(a)= 42575368
# 调用后:c = [1, 2, 3] id(a)= 42574920

3.4 不定长参数

  • 定义函数时,可以在形参前面加一个*,这样这个形参可以获取到所有的实参,它会将所有的实参保存到一个元组中
  • 带*号的形参只能有一个,可以和其他参数配合使用
    • 不定长参数不是必须写在最后,但是注意 带*的参数后面的所有的形参,必须以关键字的形式来传递
def fn2(a,b,*c):print('a =',a)print('b =',b)print('c =',c)
fn2(1,2,3,4,5)
# a = 1
# b = 2
# c = (3, 4, 5)
print("----------------------------------------------------------")
# def  fn2(a,*b,*c):			# SyntaxError: invalid syntax
#     pass
print("----------------------------------------------------------")
def fn2(a,*b,c):print('a =',a)print('b =',b)print('c =',c)
# fn2(1,2,3,4,5)  # TypeError: fn2() missing 1 required keyword-only argument: 'c'
fn2(1,2,3,4,c=5)
# a = 1
# b = (2, 3, 4)
# c = 5
print("----------------------------------------------------------")
def fn2(*a,b,c):print('a =',a)print('b =',b)print('c =',c)
# fn2(1,2,3,4,c=5)    # TypeError: fn2() missing 1 required keyword-only argument: 'b'
# fn2(1,2,3,b=4,5)  # SyntaxError: positional argument follows keyword argument
fn2(1,2,3,b=4,c=5)
# a = (1, 2, 3)
# b = 4
# c = 5
  • *形参只能接受位置参数,不能接受关键字参数
# *形参只能接受位置参数,不能接受关键字参数
def fn3(*b):print('b =', b)
# fn3(b=1,d=2,c=3)    # TypeError: fn3() got an unexpected keyword argument 'b'
  • **形参可以接收其他的关键字参数,它会将这些参数统一保存到字典当中。字典的key就是参数的名字,字典的value就是参数的值
  • **形参只有一个,并且必须写在所有参数的后面
def fn3(**b):print('b =',b)
fn3(b=1,d=2,c=3)
# b = {'b': 1, 'd': 2, 'c': 3}
print("----------------------------------------------------------")
def fn3(b,c,**a):print('a =',a)print('b =',b)print('c =',c)
fn3(b=1,d=2,c=3,e=50,f=80)
# a = {'d': 2, 'e': 50, 'f': 80}
# b = 1
# c = 3
fn3(1,d=2,c=3,e=50,f=80)
# a = {'d': 2, 'e': 50, 'f': 80}
# b = 1
# c = 3
  • *b 处理的是位置参数 **a处理的是关键字参数 一般这样用:*args,**kwargs

3.5 参数的解包

  • 传递实参时,也可以在序列类型的参数前添加星号,这样它会自动的将序列中元素依次作为参数传递
  • 要求序列中的元素的个数必须和形参的个数一致
def fn3(a,b):print('a =',a,'b =',b)t = (1,2)
fn3(t[0],t[1])
fn3(*t)s =[1,2]
fn3(*s)# s= [1,2,3,4]
# fn3(*s)    #TypeError: fn3() takes 3 positional arguments but 4 were givend = {'a':1,'b':2}
fn3(**d)

4.函数的返回值

  • 返回值就是函数执行以后返回的结果
  • 通过return来指定函数的返回值
  • return后面可以跟任意对象,返回值甚至可以是一个函数
def fn():# return后面跟什么值,函数就会返回什么值# return后面可以跟任意的对象,甚至是一个函数# return 123				# 返回值int型:123# return 'python'			# 返回值字符串型:python# return [1,2,3]			# 返回值列表:[1,2,3]def fn2():print('fn函数内定义fn2函数 正在执行:hahaha')return fn2					#返回函数对象
# print(fn())
r = fn()
print(r)
r()
# <function fn.<locals>.fn2 at 0x000000000287F8C8>
# fn函数内定义fn2函数 正在执行:hahaha
  • 函数没有返回参数或没有return,则函数返回值为 None
  • 在函数中return后的代码都不会执行,return一旦执行函数自动结束
def fn3():print('函数fn3已执行,打印第一行')returnprint('函数fn3已执行,打印第二行')		#不会被执行
r = fn3()
print("r=",r,"type(r)=",type(r))
# 函数fn3已执行,打印第一行
# r= None type(r)= <class 'NoneType'>

5.档字符串

  • help()是Python中内置函数,通过help()函数可以查询Python中函数的用法
  • 在定义函数时,可以在函数内部编写文档字符串,文档字符串就是对函数的说明
def fn(a:int,b:str,c:bool) -> int:'''这是一个文档字符串的案例参数的作用:param a: 作用.... 类型... 默认值...:param b: 作用.... 类型... 默认值...:param c: 作用.... 类型... 默认值...:return:'''print("a=",a,"type(a)=",type(a))print("b=",b,"type(b)=",type(b))print("c=",c,"type(c)=",type(c))return 123help(fn)
fn(1,'abc',True)
fn(1,(1,'abc'),True# Help on function fn in module __main__:
# 
# fn(a:int, b:str, c:bool) -> int
#     这是一个文档字符串的案例
#     
#     参数的作用
#     :param a: 作用.... 类型... 默认值...
#     :param b: 作用.... 类型... 默认值...
#     :param c: 作用.... 类型... 默认值...
#     :return:
# 
# a= 1 type(a)= <class 'int'>
# b= abc type(b)= <class 'str'>
# c= True type(c)= <class 'bool'>
# a= 1 type(a)= <class 'int'>
# b= (1, 'abc') type(b)= <class 'tuple'>
# c= True type(c)= <class 'bool'>

6.函数的作用域

6.1. 作用域(scope)

  • 作用域指的是变量有效的区域
  • 在Python中有两种作用域:全局作用域 和 函数作用域

6.1.1 全局作用域

  • 全局作用域在程序执行时创建,在程序执行结束时销毁
  • 所有函数以外的区域都是全局作用域
  • 在全局作用域中定义的变量,都是全局变量,全局变量可以在程序的任意位置进行访问

6.1.2 函数作用域

  • 函数作用域在函数调用时创建,在调用结束时销毁
  • 函数每调用一次就会产生一个新的函数作用域
  • 在函数作用域中定义的变量,都是局部变量,它只能在函数内部被访问
  • 函数中可以再定义函数,函数作用域内可以包含内部函数作用域
  • 作用域 能从内向外看,但不能从外向内看
b = 20
def fn1():def fn2():a = 30# a定义在了函数fn3内部,所有它的作用域就是函数内部,函数外部访问不到print("fn2中:a =",a)print("fn2中:b =",b)        fn2()# print("fn1中:a =", a)		# NameError: name 'a' is not definedprint("fn1中:b =", b)
fn1()
print('函数外部:', 'b =', b)
# print('函数外部:', 'a =', a)        # NameError: name 'a' is not defined
# fn2中:a = 30
# fn2中:b = 20
# fn1中:b = 20
# 函数外部: b = 20

-如果希望在函数内部修改全局变量,则需要使用一个global关键字,来声明变量,然后再修改值

b=20
print("函数调用前 b =",b)
def fn4():# 如果希望在函数内部修改全局变量,则需要使用一个global关键字,来声明变量global a # 声明在函数内部的使用a是全局变量,此时我们修改a,就是在修改全局变量b = 80print('函数内部:', 'b =', b)fn4()
print('函数外部:','b =',b)
# 函数调用前 b = 20
# 函数内部: b = 80
# 函数外部: b = 80

7.递归函数

  • 递归简单理解就是自己去引用自己,是解决问题的一种方式,它的整体思想,是将一个大问题分解为一个个的小问题,直到问题无法分解时,在去解决问题
  • 递归函数就是在函数中调用自己

7.1.递归式函数有2个条件

  1. 基线条件:问题可以被分解为最小问题,当满足基线条件时,递归就不执行了
  2. 递归条件:可以将问题继续分解的条件
# 求10的阶乘 (10!)
# 方法一:直接乘
print(1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10)
# 3628800# 方法二:for循环
n = 10
for i in range(1, 10):n *= i
print(n)#方法三:函数:for循环
def fn(n):# 参数n 用来求任意数的阶乘# 创建一个变量来保存结果r = n  # 将最后一个数直接赋值初始值,再乘n-1个数for i in range(1, n):r *= ireturn r
print(fn(10))# 方法四:递归函数
def fn2(n):# 参数n 要求阶乘的数字# 基线条件:判断n为1的时候 就不递归了if n == 1:# 1的阶乘就是它本身 1return 1else:#递归条件:  n * (n-1)!return n * fn2(n - 1)print(fn2(10))

7.2.递归经典练习

7.2.1 任意正整数的阶乘 n!= n*(n-1)!= n*(n-1) 2*1

  • 基线条件:判断n为1的时候 就不递归了
  • 递归条件: n * (n-1)!
def fn2(n):    # 参数n 要求阶乘的数字if n == 1:# 1的阶乘就是它本身 1return 1else:# 递归条件:  n * (n-1)!return n * fn2(n - 1)

7.2.1 任意正整数的n次幂 nm=n*[n(m-1)]=n*…*n

  • 基线条件:当m=1 时,n**m=n
  • 递归条件:n* [n**(m-1)]
# 10 ** 5 = 10 * 10 ** 4
# 10 ** 4 = 10 * 10 ** 3
# ...
# 10 ** 1 = 10
def fn1(n,i):# 参数 n 做幂运算的数字 i 做幂运算的次数# 基线条件if i == 1:return n# 递归条件return n * fn1(n,i-1)print(fn1(5,8))
print(5 ** 8)

7.2.2 检查一个任意字符串是否是回文字符串。如果是就返回True 不是就返回False

  • 什么是回文字符串? 字符串从后往前念和从前往后念是一样的 例如 aba abcba b abcdefgfedcba

    • 先检查第一个字符和最后一个字符是否一致,如果不一致一定不是回文
    • 如果第一个字符和最后一个字符一致。看其余的部分是不是回文字符串
    • 检查 bcdefgfedcb 是不是回文字符串
    • 检查 cdefgfedc 是不是回文字符串
    • 检查 defgfed 是不是回文字符串
    • 检查 fgf 是不是回文字符串
    • 检查 g 是不是回文字符串
  • 基线条件:

if len(s) < 2:
字符串的长度小于2 则字符串一定是回文字符串
return True
elif s[0] != s[-1]:
第一个字符和最后一个字符不相等 不是回文字符串
return False

  • 递归条件: return fn2(s[1:-1])
#简化后的代码
def fn2(s):# 参数 s 要检查的字符串# 基线条件# if len(s) < 2:#     # 字符串的长度小于2 则字符串一定是回文字符串#     return True# elif s[0] != s[-1]:#     # 第一个字符和最后一个字符不相等 不是回文字符串#     return False# # 递归条件# return fn2(s[1:-1])if len(s) < 2:return Truereturn s[0] == s[-1] and fn2(s[1:-1])

7.2.3 汉诺塔

在这里插入图片描述

详见:汉诺塔完整代码及分析

  • 简易代码效果及源码如下:
    在这里插入图片描述
'''
汉诺塔游戏,现在有ABC三根柱。要求:将A柱所有的圆盘放到C柱。在移动的过程中可以借助B柱。并且规定大圆盘不能放小圆盘上,每次只能移动一个盘子。用递归的方式来解决汉诺塔问题。
'''def huanruota(level,a,b,c):if level==1:print(f"将{level}层圆盘从 {a} 搬到 {c}")else:huanruota(level-1,a,c,b)print(f"将{level}层圆盘从 {a} 搬到 {c}")huanruota(level-1,b,a,c)def main():while True:print("需要输入汉诺塔的层数数字,如9层,输入数字9,输入q表示放弃即既退出")level_str=input("请输入数字(1-9)或 q :").strip()if level_str not in "123456789qQ" or len(level_str)>1:print("请输入正确的数字,层数过大,系统会崩溃的!!!\n")continueelif level_str=="q" or level_str=="Q":breaklevel= int(level_str)huanruota(level,"A柱","B柱","C柱")if __name__=="__main__":main()

8.命名空间

  • 命名空间实际上就是一个字典,是一个专门用来存储变量的字典
  • locals()用来获取当前作用域的命名空间
a = 80
b = 30scope = locals() # 获取当前的命名空间
print(scope)
print("a=",a)
print('scope["a"]=',scope["a"])
  • 向scope中添加一个key-value (就相当于在全局中创建了一个变量),不建议这样使用
  • 但在函数作用域内,向scope中添加一个key-value,不能被引用,会报错
scope = locals()  # 获取当前的命名空间
scope['c'] = 123
print(c)
# 123def fn4():scope = locals()  # 要获取函数内部的命名空间print(scope)
fn4()
# {}def fn4():a = 20scope = locals()  # 要获取函数内部的命名空间print(scope)
fn4()
# {'a': 20}def fn4():a = 20scope = locals()  # 要获取函数内部的命名空间scope['d'] = 200# print(d)      #  NameError: name 'd' is not definedprint(scope)# print("d=",d)  #  NameError: name 'd' is not defined
fn4()
# {'a': 20, 'd': 200}
  • 如果在全局作用域中调用locals()则获取全局命名空间,如果在函数作用域中调用locals()则获取函数命名空间
  • 返回值是一个字典
b=30
scope = locals()  # 获取当前的命名空间
scope['c'] = 123
def fn4():a = 20# globals() # 这个函数可以在任意位置获取全局的命名空间global_scope = globals()print(global_scope)
fn4()
# {
# 	'__name__': '__main__', 
# 	'__doc__': None, 
# 	'__package__': None, 
# 	'__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x00000000005BA208>, 
# 	'__spec__': None, '__annotations__': {},
# 	 '__builtins__': <module 'builtins' (built-in)>,
# 	 '__file__': 'E:/DevProjects/python-course/homework_zero_class/lesson9/test.py', 
# 	 '__cached__': None, 
# 	 'b': 30, 
# 	 'scope': {...}, 
# 	 'c': 123, 
# 	 'fn4': <function fn4 at 0x000000000239F840>
# }

http://www.ppmy.cn/news/542787.html

相关文章

处理 JavaScript 异步操作的几种方法总结

引言 js的异步操作&#xff0c;已经是一个老生常谈的话题&#xff0c;关于这个话题的文章随便google一下都可以看到一大堆。处理js的异步操作&#xff0c;都有一些什么方法呢&#xff1f;仁者见仁智者见智 一、回调函数 传说中的“callback hell”就是来自回调函数。而回调函…

leetcode1.两数之和

个人主页&#xff1a;平行线也会相交 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 平行线也会相交 原创 收录于专栏【LeetCode】 &#x1f353;希望我们一起努力、成长&#xff0c;共同进步。 题目链接 给定一个整数数组 nums 和一个整数目标值 target&am…

Master PDF Editor(PDF编辑工具)v5.4.04中文免费版

Master PDF Editor是一款很方便的pdf编辑工具&#xff0c;可以对pdf文件中的文字、图片等内容进行编辑&#xff0c;并支持将PDF文件导出为多种图片格式 中文设置方法&#xff1a; 点击菜单Tools--> Settings-->Language-->Chinese-Simplified即是中文版本 软件特色&…

PDF编辑软件adobe acrobat pro 9中文版

教程&#xff1a; 1、下载软件包并解压得到下列文件&#xff0c;鼠标双击AcroPro.msi 2、点击下一步。 3、填写用户名、单位&#xff0c;安装软件已自动填写&#xff0c;如果你自己有可以自行填写。 4、继续默点击下一步&#xff0c;直到显示安装 5、等待安装。 6、安装完毕。…

什么软件可以编辑PDF文件?编辑工具分享

我们想要编辑PDF文件&#xff0c;有什么工具可以编辑呢&#xff1f;PDF文件作为我们日常中经常使用的文件格式之一&#xff0c;对它的编辑需求可以说是极大的&#xff0c;如对文件的错误地方修改、作标注、删除页面等&#xff0c;但大家都知道PDF文件不易修改&#xff0c;那我们…

Windows系统下的PDF编辑工具软件-PDF编辑器下载

PDF编辑器是一款Windows系统下的PDF编辑工具软件&#xff0c;它支持修改编辑PDF文件并向PDF添加文字、擦除内容、插入图片、绘制直线、加椭圆框、加矩形框和旋转PDF等功能。PDF编辑器可以让您在PDF文件的任何位置添加文字、删除内容、加图片或进行其他编辑&#xff0c;简单的如…

最强大的PDF编辑器Adobe Acrobat DC Pro

前言 PDF&#xff08;Portable Document Format的简称&#xff0c;意为“便携式文档格式”&#xff09;&#xff0c;是由Adobe Systems用于与应用程序、操作系统、硬件无关的方式进行文件交换所发展出的文件格式。无论在哪种打印机上都可保证精确的颜色和准确的打印效果&#…

PDF修改页码如何在中文版PDF编辑器内达成

大家从小到大一直都会接触的东西是什么呢&#xff1f; 没错&#xff01;那就是书籍&#xff0c;在幼儿园时会有故事书&#xff0c;到了小学初中高中大学会有课本&#xff0c;就算毕了业大家已经开始步入社会工作还会有工作资料书籍。俗话说得好&#xff1a;活到老学到老。书籍是…