第三天:

python的基础知识

1.Python3 函数

函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。

函数能提高应用的模块性,和代码的重复利用率。你已经知道Python提供了许多内建函数,比如print()。但你也可以自己创建函数,这被叫做 用户自定义函数

1.1定义一个函数

你可以定义一个由自己想要功能的函数,以下是简单的规则:

  • 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ()。
  • 任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。
  • 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
  • 函数内容以冒号 : 起始,并且缩进。
  • return [表达式] 结束函数,选择性地返回一个值给调用方,不带表达式的 return 相当于返回 None。

语法:
语法
Python 定义函数使用 def 关键字,一般格式如下:

def 函数名(参数列表):函数体

计算机面积的实例:

#计算面积
def welcome(name):return namedef area(length,width):return width*lengthprint('欢迎你:',welcome('张三'))
print('面积是:',area(5,3))

结果:

欢迎你: 张三
面积是: 15

1.2函数调用

定义一个函数:给了函数一个名称,指定了函数里包含的参数,和代码块结构。

这个函数的基本结构完成以后,你可以通过另一个函数调用执行,也可以直接从 Python 命令提示符执行。

# 定义函数
def printme( str ):# 打印任何传入的字符串print (str)return# 调用函数
printme("我要调用用户自定义函数!")
printme("再次调用同一函数")

1.3参数传递

在 python 中,类型属于对象,变量是没有类型的:

可更改(mutable)与不可更改(immutable)对象

在 python 中,strings, tuples, 和 numbers 是不可更改的对象,而 list,dict 等则是可以修改的对象。

不可变类型:变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变 a 的值,相当于新生成了 a。

可变类型:变量赋值 la=[1,2,3,4] 后再赋值 la[2]=5 则是将 list la 的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了。

python 函数的参数传递:

不可变类型:类似 C++ 的值传递,如整数、字符串、元组。如 fun(a),传递的只是 a 的值,没有影响 a 对象本身。如果在 fun(a) 内部修改 a 的值,则是新生成一个 a 的对象。

可变类型:类似 C++ 的引用传递,如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后 fun 外部的 la 也会受影响

python 中一切都是对象,严格意义我们不能说值传递还是引用传递,我们应该说传不可变对象和传可变对象。

不可变的实例对象:


def change(a):print(id(a))   # 指向的是同一个对象a=10print(id(a))   # 一个新对象a=1
print(id(a))
change(a)
1978023110960
1978023110960
1978023111248

传可变对象实例
可变对象在函数里修改了参数,那么在调用这个函数的函数里,原始的参数也被改变了。例如:

实例(Python 3.0+)
#!/usr/bin/python3

可写函数说明

def changeme( mylist ):"修改传入的列表"mylist.append([1,2,3,4])print ("函数内取值: ", mylist)return

调用changeme函数

mylist = [10,20,30]
changeme( mylist )
print ("函数外取值: ", mylist)

传入函数的和在末尾添加新内容的对象用的是同一个引用。故输出结果如下:

函数内取值:  [10, 20, 30, [1, 2, 3, 4]]
函数外取值:  [10, 20, 30, [1, 2, 3, 4]]

1.4参数

以下是调用函数时可使用的正式参数类型:

  • 必需参数
  • 关键字参数
  • 默认参数
  • 不定长参数

必需参数

必需参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样。

调用 printme() 函数,你必须传入一个参数,不然会出现语法错误

关键字参数

关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值。

使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值。

以下实例在函数 printme() 调用时使用参数名:

#关键字参数
def importzi(str1,str2):print(str1,str2)return 0
importzi(str1='你好',str2='world')

默认参数

调用函数时,如果没有传递参数,则会使用默认参数。以下实例中如果没有传入 age 参数,则使用默认值:

实例:

#可写函数说明
def imformation(name,age=10):print("姓名:",name)print("年龄:",age)return
#调用printinfo函数
imformation('里斯')
imformation('里斯',25)

结果:

姓名: 里斯
年龄: 10
姓名: 里斯
年龄: 25

不定长参数

你可能需要一个函数能处理比当初声明时更多的参数。这些参数叫做不定长参数,和上述 2 种参数不同,声明时不会命名

加了星号 * 的参数会以元组(tuple)的形式导入,存放所有未命名的变量参数。


def nolength(var1,*var2):print("输出:")print(var1)print(var2)nolength(20,10,100,1)
输出:
20
(10, 100, 1)

加了两个星号 ** 的参数会以字典的形式导入

可写函数说明

def printinfo( arg1, **vardict ):"打印任何传入的参数"print ("输出: ")print (arg1)print (vardict)
*调用printinfo 函数*
printinfo(1, a=2,b=3)

以上实例输出结果:

输出:
1
{'a': 2, 'b': 3}

声明函数时,参数中星号 * 可以单独出现,
例如:

def f(a,b,*,c):return a+b+c

如果单独出现星号 * 后的参数必须用关键字传入

def f(a,b,*,c):   return a+b+cf(1,2,3)   # 报错
Traceback (most recent call last):File "<stdin>", line 1, in <module>
TypeError: f() takes 2 positional arguments but 3 were given
>>> f(1,2,c=3) # 正常
6
>>>

1.5匿名函数

python 使用 lambda 来创建匿名函数。

所谓匿名,意即不再使用 def 语句这样标准的形式定义一个函数。

  • lambda 只是一个表达式,函数体比 def 简单很多。
  • lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
  • lambda函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。
  • 虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。

语法
lambda 函数的语法只包含一个语句,如下:

lambda [arg1 [,arg2,…argn]]:expression

sum=lambda a1,a2:a1+a2print("相加之后的值:",sum(10,20))
print("相加之后的值:",sum(20,20))Sumstring=lambda b1,b2:b1+b2print(Sumstring('aaa','ddd'))
print(Sumstring('你好','世界'))
相加之后的值: 30
相加之后的值: 40
aaaddd
你好世界

1.6return语句

return [表达式]语句用于退出函数,选择性地向调用方返回一个表达式。不带参数值的return语句返回None。之前的例子都没有示范如何返回数值

以下实例演示了 return 语句的用法:

实例(Python 3.0+)

可写函数说明
def sum( arg1, arg2 ):# 返回2个参数的和."total = arg1 + arg2print ("函数内 : ", total)return total
调用sum函数
total = sum( 10, 20 )
print ("函数外 : ", total)

以上实例输出结果:

函数内 :  30
函数外 :  30

2.Python3 数据结构

Python中列表是可变的,这是它区别于字符串和元组的最重要的特点,一句话概括即:列表可以修改,而字符串和元组不能

2.1将列表当做堆栈使用

列表方法使得列表可以很方便的作为一个堆栈来使用,堆栈作为特定的数据结构,最先进入的元素最后一个被释放(后进先出)。用 append() 方法可以把一个元素添加到堆栈顶。用不指定索引的 pop() 方法可以把一个元素从堆栈顶释放出来

stack=[1,2,3]
stack.append(4)
stack.append(5)print(stack)print(stack.pop())
print(stack.pop())
[1, 2, 3, 4, 5]
5
4

2.2将列表当作队列使用

也可以把列表当做队列用,只是在队列里第一加入的元素,第一个取出来;但是拿列表用作这样的目的效率不高。

在列表的最后添加或者弹出元素速度快,然而在列表里插入或者从头部弹出速度却不快(因为所有其他的元素都得一个一个地移动)。

from collections import deque
queue=deque(['json','jack','tom'])
queue.append('laj')
queue.append('mack')
print(queue)
print(queue.popleft())
print(queue.popleft())

结果:

deque(['json', 'jack', 'tom', 'laj', 'mack'])
json
jack

2.3元组和序列

元组由若干逗号分隔的值组成

例如:

>>> t = 12345, 54321, 'hello!'
>>> t[0]
12345
>>> t
(12345, 54321, 'hello!')
>>> # Tuples may be nested:
... u = t, (1, 2, 3, 4, 5)
>>> u
((12345, 54321, 'hello!'), (1, 2, 3, 4, 5))

如你所见,元组在输出时总是有括号的,以便于正确表达嵌套结构。在输入时可能有或没有括号, 不过括号通常是必须的(如果元组是更大的表达式的一部分)。

2.4集合


集合是一个无序不重复元素的集。基本功能包括关系测试和消除重复元素

可以用大括号({})创建集合。注意:如果要创建一个空集合,你必须用 set() 而不是 {} ;后者创建一个空的字典,下一节我们会介绍这个数据结构。

2.5字典

另一个非常有用的 Python 内建数据类型是字典。

序列是以连续的整数为索引,与此不同的是,字典以关键字为索引,关键字可以是任意不可变类型,通常用字符串或数值。

理解字典的最佳方式是把它看做无序的键=>值对集合。在同一个字典之内,关键字必须是互不相同。

一对大括号创建一个空的字典:{}。

3.Python3 模块

在前面的几个章节中我们基本上是用 python 解释器来编程,如果你从 Python 解释器退出再进入,那么你定义的所有的方法和变量就都消失了。

为此 Python 提供了一个办法,把这些定义存放在文件中,为一些脚本或者交互式的解释器实例使用,这个文件被称为模块。

模块是一个包含所有你定义的函数和变量的文件,其后缀名是.py。模块可以被别的程序引入,以使用该模块中的函数等功能。这也是使用 python 标准库的方法

3.1import 语句

想使用 Python 源文件,只需在另一个源文件里执行 import 语句,语法如下:

import module1[, module2[,… moduleN]

当解释器遇到 import 语句,如果模块在当前的搜索路径就会被导入。

搜索路径是一个解释器会先进行搜索的所有目录的列表。如想要导入模块 support,需要把命令放在脚本的顶端:

support.py 文件代码
#!/usr/bin/python3Filename: support.pydef print_func( par ):print ("Hello : ", par)return
test.py 引入 support 模块:test.py 文件代码
#!/usr/bin/python3Filename: test.py导入模块
import support
现在可以调用模块里包含的函数了
support.print_func("Runoob")

输出:

Hello :  Runoob

一个模块只会被导入一次,不管你执行了多少次import。这样可以防止导入模块被一遍又一遍地执行。

当我们使用import语句的时候,Python解释器是怎样找到对应的文件的呢?

这就涉及到Python的搜索路径,搜索路径是由一系列目录名组成的,Python解释器就依次从这些目录中去寻找所引入的模块。

这看起来很像环境变量,事实上,也可以通过定义环境变量的方式来确定搜索路径。

搜索路径是在Python编译或安装的时候确定的,安装新的库应该也会修改。

3.2深入模块

模块除了方法定义,还可以包括可执行的代码。这些代码一般用来初始化这个模块。这些代码只有在第一次被导入时才会被执行。

每个模块有各自独立的符号表,在模块内部为所有的函数当作全局符号表来使用。

所以,模块的作者可以放心大胆的在模块内部使用这些全局变量,而不用担心把其他用户的全局变量搞混。

从另一个方面,当你确实知道你在做什么的话,你也可以通过 modname.itemname 这样的表示法来访问模块内的函数。

模块是可以导入其他模块的。在一个模块(或者脚本,或者其他地方)的最前面使用 import 来导入一个模块,当然这只是一个惯例,而不是强制的。被导入的模块的名称将被放入当前操作的模块的符号表中。

3.3__name__属性

一个模块被另一个程序第一次引入时,其主程序将运行。如果我们想在模块被引入时,模块中的某一程序块不执行,我们可以用__name__属性来使该程序块仅在该模块自身运行时执行。

if __name__ == '__main__':print('程序自身在运行')
else:print('我来自另一模块')

运行输出如下:

程序自身在运行
>>> import using_name
我来自另一模块
>>>

说明:

每个模块都有一个__name__属性,当其值是’main’时,表明该模块自身在运行,否则是被引入。

说明:
__name__ 与 __main__ 底下是双下划线, _ _ 是这样去掉中间的那个空格

3.4dir() 函数

内置的函数 dir() 可以找到模块内定义的所有名称。以一个字符串列表的形式返回

3.5标准模块

Python 本身带着一些标准的模块库,在 Python 库参考文档中将会介绍到(就是后面的"库参考文档")。

有些模块直接被构建在解析器里,这些虽然不是一些语言内置的功能,但是他却能很高效的使用,甚至是系统级调用也没问题。

这些组件会根据不同的操作系统进行不同形式的配置,比如 winreg 这个模块就只会提供给 Windows 系统。

应该注意到这有一个特别的模块 sys ,它内置在每一个 Python 解析器中。变量 sys.ps1 和 sys.ps2 定义了主提示符和副提示符所对应的字符串:

3.6包

包是一种管理 Python 模块命名空间的形式,采用"点模块名称"。

比如一个模块的名称是 A.B, 那么他表示一个包 A中的子模块 B 。

就好像使用模块的时候,你不用担心不同模块之间的全局变量相互影响一样,采用点模块名称这种形式也不用担心不同库之间的模块重名的情况。

这样不同的作者都可以提供 NumPy 模块,或者是 Python 图形库。

不妨假设你想设计一套统一处理声音文件和数据的模块(或者称之为一个"包")。

现存很多种不同的音频文件格式(基本上都是通过后缀名区分的,例如: .wav,:file:.aiff,:file:.au,),所以你需要有一组不断增加的模块,用来在不同的格式之间转换。

并且针对这些音频数据,还有很多不同的操作(比如混音,添加回声,增加均衡器功能,创建人造立体声效果),所以你还需要一组怎么也写不完的模块来处理这些操作。

这里给出了一种可能的包结构(在分层的文件系统中):

sound/                          顶层包__init__.py               初始化 sound 包formats/                  文件格式转换子包__init__.pywavread.pywavwrite.pyaiffread.pyaiffwrite.pyauread.pyauwrite.py...effects/                  声音效果子包__init__.pyecho.pysurround.pyreverse.py...filters/                  filters 子包__init__.pyequalizer.pyvocoder.pykaraoke.py...

在导入一个包的时候,Python 会根据 sys.path 中的目录来寻找这个包中包含的子目录。

目录只有包含一个叫做 __init__.py 的文件才会被认作是一个包,主要是为了避免一些滥俗的名字(比如叫做 string)不小心的影响搜索路径中的有效模块。

最简单的情况,放一个空的 :file:init.py就可以了。当然这个文件中也可以包含一些初始化代码或者为(将在后面介绍的) __all__变量赋值。

4.Python3 输入和输出

4.1输出格式美化

Python两种输出值的方式: 表达式语句print() 函数

第三种方式是使用文件对象的 write() 方法,标准输出文件可以用 sys.stdout 引用。

如果你希望输出的形式更加多样,可以使用 str.format() 函数来格式化输出值。

如果你希望将输出的值转成字符串,可以使用 repr() 或 str() 函数来实现。

str(): 函数返回一个用户易读的表达形式。
repr(): 产生一个解释器易读的表达形式。

4.2旧式字符串格式化

% 操作符也可以实现字符串格式化。 它将左边的参数作为类似 sprintf() 式的格式化字符串, 而将右边的代入, 然后返回格式化后的字符串.

>>> import math
>>> print('常量 PI 的值近似为:%5.3f。' % math.pi)
常量 PI 的值近似为:3.142。

因为 str.format() 是比较新的函数, 大多数的 Python 代码仍然使用 % 操作符。但是因为这种旧式的格式化最终会从该语言中移除, 应该更多的使用 str.format().

4.3读和写文件

open() 将会返回一个 file 对象,基本语法格式如下:

open(filename, mode)

filename:包含了你要访问的文件名称的字符串值。

mode:决定了打开文件的模式:只读,写入,追加等。所有可取值见如下的完全列表。这个参数是非强制的,默认文件访问模式为只读®。

4.4 文件对象的方法

f.read()

为了读取一个文件的内容,调用 f.read(size), 这将读取一定数目的数据, 然后作为字符串或字节对象返回。

size 是一个可选的数字类型的参数。 当 size 被忽略了或者为负, 那么该文件的所有内容都将被读取并且返回。

f.readline()
f.readline() 会从文件中读取单独的一行。换行符为 ‘\n’。f.readline() 如果返回一个空字符串, 说明已经已经读取到最后一行。

实例

# 打开一个文件
f = open("/tmp/foo.txt", "r")str = f.readline()
print(str)
# 关闭打开的文件
f.close()
执行以上程序,输出结果为:Python 是一个非常好的语言

f.readline()

f.readline() 会从文件中读取单独的一行。换行符为 ‘\n’。f.readline() 如果返回一个空字符串,
说明已经已经读取到最后一行。

f.readlines()

f.readlines() 将返回该文件中包含的所有行。

如果设置可选参数 sizehint, 则读取指定长度的字节, 并且将这些字节按行分割。

实例

# 打开一个文件
f = open("/tmp/foo.txt", "r")str = f.readlines()
print(str)# 关闭打开的文件
f.close()

执行以上程序,输出结果为:

['Python 是一个非常好的语言。\n', '是的,的确非常好!!\n']

f.tell()

f.tell() 返回文件对象当前所处的位置, 它是从文件开头开始算起的字节数。

f.seek()
如果要改变文件当前的位置, 可以使用 f.seek(offset, from_what) 函数。

from_what 的值, 如果是 0 表示开头, 如果是 1 表示当前位置, 2 表示文件的结尾,例如:

seek(x,0) : 从起始位置即文件首行首字符开始移动 x 个字符
seek(x,1) : 表示从当前位置往后移动x个字符
seek(-x,2):表示从文件的结尾往前移动x个字符

f.close()

在文本文件中 (那些打开文件的模式下没有 b 的), 只会相对于文件起始位置进行定位。

当你处理完一个文件后, 调用 f.close() 来关闭文件并释放系统的资源,如果尝试再调用该文件,则会抛出异常

pickle 模块

python的pickle模块实现了基本的数据序列和反序列化。

通过pickle模块的序列化操作我们能够将程序中运行的对象信息保存到文件中去,永久存储。

通过pickle模块的反序列化操作,我们能够从文件中创建上一次程序保存的对象。

基本接口:

pickle.dump(obj, file, [,protocol])

有了 pickle 这个对象, 就能对 file 以读取的形式打开:

x = pickle.load(file)

注解:从 file 中读取一个字符串,并将它重构为原来的python对象。

file: 类文件对象,有read()和readline()接口。

5.Python3 File(文件) 方法

5.1open() 方法
Python open() 方法用于打开一个文件,并返回文件对象,在对文件进行处理过程都需要使用到这个函数,如果该文件无法被打开,会抛出 OSError。

注意:使用 open() 方法一定要保证关闭文件对象,即调用 close() 方法。

open() 函数常用形式是接收两个参数:文件名(file)和模式(mode)。

完整的语法格式为:

open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

参数说明:

  • file: 必需,文件路径(相对或者绝对路径)。
  • mode: 可选,文件打开模式
  • buffering: 设置缓冲
  • encoding:一般使用utf8
  • errors: 报错级别
  • newline: 区分换行符
  • closefd: 传入的file参数类型
  • opener:设置自定义开启器,开启器的返回值必须是一个打开的文件描述符。

python实习——03相关推荐

  1. python实习做什么工作-大一/大二学生Python实习的困惑?

    题主是一名非名校的CS本科学生,现在遇到了一些困惑,想请教一下热心的segmentfault网友.因为不是985/211名校,现在题主所在的这所学校我感觉学风非常不好,第一是整体水平太低,一学期结束了 ...

  2. python基础03/字典

    python基础03/字典 内容大纲 1.字典 1.字典 字典是无序,可变的数据类型 字典:用于存储数据,储存大量数据,字典要比列表快 1.1 定义一个列表 lst1 = ["老大" ...

  3. 菜鸟Python实战-03爬虫之爬取数据

    最近想学习一下爬虫 所以参考了一下网上的代码,并加以理解和整理,好记性不如烂笔头吧. 以下代码的目标网站是豆瓣电影:https://movie.douban.com/top250?start=%22( ...

  4. 计算机大三了只会python可以去名企实习吗?如何找python实习

    知乎上有人问"软工大三下了,只会python,还没找到实习怎么办?",关于这个问题,网友的答复很是耿直,比如 网友1的答复是:找工作了才只会个简单的django项目,人家公司招人是 ...

  5. python实习内容过程_对Python实习的简单分析,也许可以帮到你

    昨天对实习僧抓取了90条Python实习的数据,今天做一个简单的分析. 因为实习僧网站上关于Python实习岗位太少,所以以下内容进仅供娱乐. 各个地点的平均日工资,南京竟然比上海还高.回去筛选一看, ...

  6. python实习目的_python爬虫系列---为什么要学习爬虫

    (0)为什么要学习爬虫 最近刷抖音看到一个话题是"为什么要找程序员老公?",其中一条理由是:写个python网络投票爬虫,稳稳让自家孩子成为幼儿园最美宝宝.当然这算是爬虫的其中一个 ...

  7. Python中级 —— 03进程与线程

    多任务的实现有3种方式: 多进程模式: 多线程模式: 多进程+多线程模式. ** 进程: ** 不同任务,例如打开一个写字本,就是开启一个新进程. 多进程 Unix/Linux操作系统提供了一个for ...

  8. python 系列 03 - 基于scrapy框架的简单爬虫

    文章目录 1. scrapy介绍 2 新建爬虫项目 3 新建蜘蛛文件 4 运行爬虫 5 爬取内容 5.1分析网页结构 5.2 关于Xpath解析 5.3 接着解析电影数据 5.4 下载缩略图 5.5 ...

  9. python实习做什么工作-面试python实习工作需要注意哪些事项???

    一.语言 1.推荐一本看过较好的python书籍? 拉开话题好扯淡 2.谈谈python的装饰器,迭代器,yield? 3.标准库线程安全的队列是哪一个?不安全的是哪一个?logging是线程安全的吗 ...

最新文章

  1. 微软企业服务部华东区招聘顾问/架构师/.NET高级开发员
  2. 3d人脸重建 facescape 测试
  3. 元素周期表排列的规律_元素周期表诞生150周年,这些有趣的元素性质你都知道吗?...
  4. NOSQL 之 cassadra 安装与集群配置
  5. java基础1之java语言基础1
  6. python支持复数以及相关的运算吗_Python: 复数的数学运算
  7. toj 4315 一二三
  8. struts2 表单 get 乱码问题/apache+tomcat+jk 乱码问题
  9. UWP,WPF 打包Roboto 字体
  10. CVPR'22 最新132篇论文分方向整理|包含目标检测、图像处理、医学影像等28个方向...
  11. 把读书当做信仰的民族:犹太民族
  12. DragonBones(龙骨动画)在Unity端的使用
  13. win 10 计算机找不到,怎么找到win10的计算器?不见了,怎么处理
  14. LPMS-IMU姿态解算
  15. [大话设计模式C++版] 第17章 在NBA我需要翻译 —— 适配器模式
  16. Windows版Redis和Redis Desktop Manager安装
  17. x86保护模式——全局描述符表GDT详解
  18. 推荐系统入门(七):新闻推荐实践2(附代码)
  19. URLEncode 解释
  20. 2014 年放弃阿里巴巴offer 的人是否格外多?如果是,为什么?

热门文章

  1. 全国计算机建模三等奖,青春榜样 | 吴昊 : 守得云开见月明
  2. osgearth仿真平台(1)
  3. LocalDate,LocalDateTime获取每周,每月,每年的第一天和最后一天,获取一周七天的日期,获取每月的所有日期
  4. linux如何查看内存大小
  5. OpenBmc开发错误6:gyp ERR! configure error gyp ERR! stack Error: socket hang up
  6. 机器学习:随机森林原理 OOB等
  7. 当代超吸金的行业“Python工程师”,如何快速从Pytho入门到初级Python工程师?
  8. 学计算机广告制作用什么电脑,大学设计专业电脑配置须知
  9. python数据不足位数补0
  10. 图书管理系统的c实现用于图书信息的管理。