数据类型
- Number(数字)
- int(整型)
- float(浮点型)
- complex(复数)
- String(字符串)
- List(列表)
- Tuple(元组)
- Set(集合)
- Dictionary(字典)
- Number(数字)
字符串
字符串的输入
- 单引号/双引号; 单引号
- 三个引号1234567- **字符转义**:- `\ (反斜杠)`- `r`` ` 引号内部的字符串默认都不转义```pythonr`ABC\.CSV$`
合并 :运用加号 ( + ) 来进行合并字符串
空白
- 添加空白:制表符 (\t) 、换行符(\n)
- 删除空白:两侧 - strip();左侧 - lstrip();右侧 - rstrip()
赋值与变更 : 必须将变更后的对象赋值,因为字符串是不可更改的;
f = f.strip()
字符串 *(星号) 数字;表示字符串重复输出n次
print("." * 10)
转换 : str()
长度:len(string)
格式化
- 用%来实现字符串的格式化
|
|
字符串 | 含义 |
---|---|
%d - digit | 整数 |
%f - float | 浮点数 |
%s - string | 字符串 |
%x | 十六进制整数 |
%% | 一个% |
如果你不太确定应该用什么,%s永远起作用,它会把任何数据类型转换为字符串
布尔值
- and / or / not
空值
- None,一个特殊的空值
可变与不可变对象
- str是不变对象,而list是可变对象
- 对于可变对象,比如list,对list进行操作,list内部的内容是会变化的
- 对于不可变对象,比如str,对str进行操作,str内部是不变的。
|
|
- 始终牢记的是,a是变量,而’abc’才是字符串对象!有些时候,我们经常说,对象a的内容是’abc’,但其实是指,a本身是一个变量,它指向的对象的内容才是’abc’ 。
- 当我们调用a.replace(‘a’, ‘A’)时,实际上调用方法replace是作用在字符串对象’abc’上的,而这个方法虽然名字叫replace,但却没有改变字符串’abc’的内容。相反,replace方法创建了一个新字符串’Abc’并返回,如果我们用变量b指向该新字符串,就容易理解了,变量a仍指向原有的字符串’abc’,但变量b却指向新字符串’Abc’了
- 对于不变对象来说,调用对象自身的任意方法,也不会改变该对象自身的内容。相反,这些方法会创建新的对象并返回,这样,就保证了不可变对象本身永远是不可变的。
数据类型转换
函数 | 描述 |
---|---|
int(x [,base]) | 将x转换为一个整数 |
long(x [,base] ) | 将x转换为一个长整数 |
float(x) | 将x转换到一个浮点数 |
complex(real [,imag]) | 创建一个复数 |
str(x) | 将对象 x 转换为字符串 |
repr(x) | 将对象 x 转换为表达式字符串 |
eval(str) | 用来计算在字符串中的有效Python表达式,并返回一个对象 |
tuple(s) | 将序列 s 转换为一个元组 |
list(s) | 将序列 s 转换为一个列表 |
set(s) | 转换为可变集合 |
dict(d) | 创建一个字典。d 必须是一个序列 (key,value)元组。 |
frozenset(s) | 转换为不可变集合 |
chr(x) | 将一个整数转换为一个字符 |
unichr(x) | 将一个整数转换为Unicode字符 |
ord(x) | 将一个字符转换为它的整数值 |
hex(x) | 将一个整数转换为一个十六进制字符串 |
oct(x) | 将一个整数转换为一个八进制字符串 |
数据结构
元组 - tuple
- what :元组是一种不可变序列
- 元组和列表一样可以使用索引、切片来取值。
- 创建元组后不能在原地进行修改替换等操作
- 元组支持嵌套,可以包含列表、字典和不同元组
- why :元组的不可变性,在保证一个程序安全方面起到很大作用。
创建tuple
- 元组是用小括号( )包括起来的,( )括号中的元素用逗号分割,这样就完成元组的创建了
- 用tuple函数进行创建
|
|
修改元组
元组是不可变的,类似字符串,不能在原处修改内容,但我们可以把它的类型做下转换,例如把一个元组转换为一个列表进行修改,之后再转换成元组。
索引 - 切片
列表list - 基本功能
- what :可以包含不同类型的数据对像,同时它是一个有序的集合;同时,它支持添加 append、插入 insert、修改、删除del等操作
1. 创建
- list列表理解为任意对像的序列,只要把需要的参数值放入到中括号[ ]里面就可以了
- 用函数list()创建
|
|
2. 查找(索引) - 切片
方括号中索引值,半闭半开区间;左侧包括,右侧不包括
- 使用方括号[ ] 与 冒号 :
- 索引从0开始;
- 最后一个列表的元素为-1 (倒数第二个为-2,从末尾开始数正常)
|
|
3. 修改
- 列表是有序的,可以通过list下标来修改特定位置的值
|
|
4. .append() / .insert() - 添加
- 末尾添加 - append(obj) / append(“string”)
- 插入元素 - insert(n, obj) /insert(n, “string”)
motorcycles.insert(0, 'ducati')
- 第一个实参n表示插入的索引位置;这种操作会使得表中所有位于该索引之后的元素往右移一个位置;
5. del & pop & remove - 删除
根据位置直接删除 - del
del motocycles[0]
根据位置删除 - pop()
- 默认情况下,弹出列表末尾的一个元素
motorcycles.pop()
- 指定索引位置,则弹出该位置的元素
motorcycle.pop(1)
- 每次只能删除一个索引位置的元素
- 默认情况下,弹出列表末尾的一个元素
根据值删除 - remove()
- remove 只删除第一个指定的值;若要删除的值在列表中出现多次,需要用循环来操作
motorcycles.remove('string')
/motorcycles.remove(obj)
如果被弹出的元素不再需要使用,就选择del
6. .sort() / sorted() - 排序
- 永久性排序 - 方法sort()
cars.sort(reverse=True)
默认按字母顺序进行升序排列 - 临时性排序 - 函数sorted()
sorted(cars, reverse = True)
7. .reverse - 反转
- 方法reverse()
cars.reverse()
反转是在原有的基础上进行颠倒;不同于按倒序排列
8. 长度 - len()
Python计算列表list元素时从1开始。但索引是从0开始的;所以,在确定列表长度时会遇到差一
列表 - 操作
1. 遍历列表 - 循环
- for循环对列表的每个元素进行访问。
|
|
使用单数、复数的名称,有利于判断是单个列表元素还是整个列表
冒号的使用
缩进的代码必须是循环的一部分;没有缩进的代码只执行一次
2. 创建数值列表- range
- 函数range() ,半闭半开区间;
|
|
3. 列表推导式
- 将for循环和创建新元素的代码合并成一行;(语法糖)
|
|
字典推导式
12 > dict_result = { key-expr: value-expr for value in collection if condition} # 区别在与用 花括号>
>
集合推导式
12 > set_result = {expr for value in collection if condition}>
4. 使用列表的一部分 - 切片/复制
- 切片 :指定第一个元素、最后一个元素的索引;
|
|
- 复制列表 :复制,两者之间没有联系。通过复制来实现
|
|
- 若直接赋值,则表示指向同一个对象;两者之间有关联;
|
|
字典 - dict
- what :字典是一系列键-值对。每个键都与一个值相关联。
一个key只能对应一个value,所以,多次对一个key放入value,后面的值会把前面的值冲掉
dict是用空间来换取时间的一种方法,并且需要牢记的第一条就是dict的key必须是不可变对象。
字符串、整数等都是不可变的,因此,可以放心地作为key
dict全称dictionary,在其他语言中也称为map
1. 创建与访问
- 创建:
- 用花括号、冒号来实现
- dict()
|
|
- 访问:指定方括号内的键
|
|
2. 添加与删除
- 添加键-值对:直接赋值,若键不存在则创建
|
|
- 删除
|
|
3. 遍历字典
- 遍历所有的键-值对 - .items()
- 遍历所有的键 - .keys()
- 遍历所有的值 - .values()
|
|
- 按顺序遍历所有的键 -
for key in sorted(user_0.keys()):
集合 - set
- what :没有重复的键。
- why :重复元素在set中自动被过滤
set和dict的唯一区别仅在于没有存储对应的value,但是,set的原理和dict一样,所以,同样不可以放入可变对象
1. 创建
创建一个set,需要提供一个list作为输入集合
|
|
传入的参数
[1, 2, 3]
是一个list,而显示的{1, 2, 3}
只是告诉你这个set内部有1,2,3这3个元素,显示的顺序也不表示set是有序的>>> s = set([1, 2, 3])>>> s{1, 2, 3}
2.添加与删除
- 添加 - .add()
- 删除 - .remove()
条件判断
1.条件测试
- 相等 ==
- 不相等 !=
- 检查多个条件:and / or
- 为改善可读性,建议加上括号
(age > 21) and (age_1 > 21)
- 为改善可读性,建议加上括号
2. 检查特定值是否包含在[列表]
- in / not in
3. if语句
- if语句
- if - else 语句
- if - elif - else 语句
它是从上往下判断,如果在某个判断上是True,把该判断对应的语句执行后,就忽略掉剩下的 elif 和 else
只要x是非零数值、非空字符串、非空list等,就判断为True,否则为False
|
|
4. input - 有问题的条件判断
input()返回的数据类型是str,str不能直接和整数比较,必须先把str转换成整数
|
|
循环
break & continue
break语句可以在循环过程中直接退出循环,而continue语句可以提前结束本轮循环,并直接开始下一轮循环。
- break
- 立即退出循环; 即该for/while循环停止,不在运行任何代码
- 嵌套循环中,仅跳出当前所在for/while循环
- continue
- 忽略余下代码,直接返回for/while循环的开头。即立刻开始第二次循环
|
|
函数
1. 定义函数
定义函数时,需要确定函数名和参数个数;
如果有必要,可以先对参数的数据类型做检查;
- 定义一个函数要使用
def
语句,依次写出函数名、括号、括号中的参数和冒号:
,然后,在缩进块中编写函数体,函数的返回值用return
语句返回。 - 函数体内部的语句在执行时,一旦执行到
return
时,函数就执行完毕,并将结果返回。 - 如果没有
return
语句,函数执行完毕后也会返回结果,只是结果为None
。
|
|
如果想定义一个什么事也不做的空函数,可以用pass语句:pass语句什么都不做.
实际上pass可以用来作为占位符,比如现在还没想好怎么写函数的代码,就可以先放一个pass,让代码能运行起来。
123 > def nop():> pass>
- 参数检查
- 调用函数时,如果参数个数不对,Python解释器会自动检查出来,并抛出TypeError:
- 当传入了不恰当的参数时,内置函数abs会检查出参数错误,而我们定义的my_abs没有参数检查,会导致if语句出错,出错信息和abs不一样。
|
|
返回多个值
12345import mathdef move(x, y, step, angle=0):nx = x + step * math.cos(angle)ny = y - step * math.sin(angle)return nx, ny
2. 参数
1. 形参与实参
- 形参:函数完成工作时所需的一项信息
- 实参:调用函数时传递给函数的信息
- 位置实参:顺序很重要
- 关键字实参:传递给函数的 名称 - 值对
2. 参数的默认值
- 在形参部分赋值
- 必选参数在前,默认参数在后
|
|
3. 可选参数(实参)
- 使用默认值让实参变为可选的:空字符串 + 置于末尾
|
|
4.1 任意数量的(可变)实参
允许传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple 【关键区别】。
- 在形参之前加上一个星号(*) : 创建一个名为numbers的空元组tuple,并将所有收到的值封装到这个元组中
|
|
- 如果已经有一个list或者tuple,要调用一个可变参数;允许你在list或tuple前面加一个星号(*),把list或tuple的元素变成可变参数传进去:
|
|
- 位置实参 + 任意数量实参 :将位置实参写在前 + 任意数量实参仍用 *形参名
|
|
4.2 任意数量的关键字实参
允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict 【关键区别】
- 形参之前加上两个星号(\) :创建一个名为person的空字典,并将收到的所有名称-值对封装到这个字典中**
- 该方式不限制关键字参数的名字
|
|
限制关键字参数的名字,就可以用命名关键字参数
- 命名关键字参数需要一个特殊分隔符*,
*
后面的参数被视为命名关键字参数 【建议采用此种命名方法】
12345def person(name, age, *, city, job):print(name, age, city, job)person('Kate', 21, args=32, city='shanghai', job='doctor')[out]: Kate 21 32 shanghai doctor- 如果函数定义中已经有了一个可变参数,后面跟着的命名关键字参数就不再需要一个特殊分隔符
*
了- 但该可变参数为元组,会用圆括号括起来
12345def person(name, age, *args, city, job):print(name, age, args, city, job)person('Kate', 21, 32, city='shanghai', job='doctor')[out]: Kate 21 (32,) shanghai doctor- 命名关键字参数需要一个特殊分隔符*,
- 命名关键字参数必须传入参数名,这和位置参数不同。如果没有传入参数名,调用将报错
- 使用命名关键字参数时,要特别注意,如果没有可变参数,就必须加一个
*
作为特殊分隔符。如果缺少*
,Python解释器将无法识别位置参数和命名关键字参数
5. 参数组合
- 参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。
- 可以用必选参数、默认参数、可变参数、关键字参数和命名关键字参数,这5种参数都可以组合使用;
|
|
- 通过一个tuple和dict,你也可以调用上述函数:
|
|
- 其他
函数名其实就是指向一个函数对象的引用,完全可以把函数名赋给一个变量,相当于给这个函数起了一个“别名” a =abs ; a(-1)
6. 参数小结
- 默认参数一定要用不可变对象,如果是可变对象,程序运行时会有逻辑错误!
- 要注意定义可变参数和关键字参数的语法:
*args
是可变参数,args接收的是一个tuple;**kw
是关键字参数,kw接收的是一个dict。- 调用函数时如何传入可变参数和关键字参数的语法:
- 可变参数既可以直接传入:
func(1, 2, 3)
,又可以先组装list或tuple,再通过*args
传入:func(*(1, 2, 3))
; - 关键字参数既可以直接传入:
func(a=1, b=2)
,又可以先组装dict,再通过**kw
传入:func(**{'a': 1, 'b': 2})
。
- 可变参数既可以直接传入:
- 使用
*args
和**kw
是Python的习惯写法,当然也可以用其他参数名,但最好使用习惯用法。 - 命名的关键字参数是为了限制调用者可以传入的参数名,同时可以提供默认值。
- 定义命名的关键字参数在没有可变参数的情况下不要忘了写分隔符
*
,否则定义的将是位置参数
3. 传递实参 - 列表
|
|
4. 返回值
函数体内部可以用return随时返回函数结果;
函数执行完毕也没有return语句时,自动return None。
函数可以同时返回多个值,但其实就是一个tuple。
- 使用return语句将值返回到函数的调用行
|
|
5. 递归函数
每个函数应只负责一项具体的工作。若执行的任务太多,可在函数中调用另一个函数
在函数内部,可以调用其他函数。所谓递归函数,一个函数在内部调用自身本身 。
举个例子,我们来计算阶乘
n! = 1 x 2 x 3 x ... x n
,用函数fact(n)
表示,可以看出:fact(n) = n! = 1 x 2 x 3 x … x (n-1) x n = (n-1)! x n = fact(n-1) x n
所以,
fact(n)
可以表示为n x fact(n-1)
,只有n=1时需要特殊处理
|
|
使用递归函数的优点是逻辑简单清晰,理论上,所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰。缺点是过深的调用会导致栈溢出。
针对尾递归优化的语言可以通过尾递归防止栈溢出。尾递归事实上和循环是等价的,没有循环语句的编程语言只能通过尾递归实现循环。
5. 保存与调用
如果你已经把my_abs()
的函数定义保存为abstest.py
文件了,那么,可以在该文件的当前目录下启动Python解释器,用from abstest import my_abs
来导入my_abs()
函数,注意abstest
是文件名(不含.py
扩展名)
|
|
函数式编程
函数是Python内建支持的一种封装,我们通过把大段代码拆成函数,通过一层一层的函数调用,就可以把复杂任务分解成简单的任务,这种分解可以称之为面向过程的程序设计。函数就是面向过程的程序设计的基本单元。
- what :函数式编程(请注意多了一个“式”字)——Functional Programming,虽然也可以归结到面向过程的程序设计,但其思想更接近数学计算。
- 计算机(Computer)和计算(Compute)
- 计算机的层次上,CPU执行的是加减乘除的指令代码,以及各种条件判断和跳转指令,所以,汇编语言是最贴近计算机的语言。
- 计算则指数学意义上的计算,越是抽象的计算,离计算机硬件越远。
- 对应到编程语言,就是越低级的语言,越贴近计算机,抽象程度低,执行效率高,比如C语言;越高级的语言,越贴近计算,抽象程度高,执行效率低,比如Lisp语言。
- 函数式编程就是一种抽象程度很高的编程范式,纯粹的函数式编程语言编写的函数没有变量
- 任意一个函数,只要输入是确定的,输出就是确定的,这种纯函数我们称之为没有副作用。
- 允许使用变量的程序设计语言,由于函数内部的变量状态不确定,同样的输入,可能得到不同的输出,因此,这种函数是有副作用的。
- 计算机(Computer)和计算(Compute)
- why :函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数!
高阶函数
变量可以指向函数
- 函数本身赋值给变量
1234567891011-10)abs(10abs<built-in function abs># abs(-10)是函数调用,而abs是函数本身。-----------------------------------------------------------------------------f = absf<built-in function abs># 说明变量f现在已经指向了abs函数本身。直接调用abs()函数和调用变量f()完全相同。函数名也是变量
函数名其实就是指向函数的变量 。对于
abs()
这个函数,完全可以把函数名abs
看成变量,它指向一个可以计算绝对值的函数!传入函数
12345678def add(x, y, f): # f = absreturn f(x) + f(y)x = -5y = 6f = absf(x) + f(y) ==> abs(-5) + abs(6) ==> 11return 11
切片&迭代
1. 切片
tuple也是一种list,唯一区别是tuple不可变。因此,tuple也可以用切片操作,只是操作的结果仍是tuple
字符串’xxx’也可以看成是一种list,每个元素就是一个字符。
- 切片 :指定第一个元素、最后一个元素的索引;
|
|
- 切片的第三个值为步长step
|
|
- 字符串的选取
|
|
- 复制列表 :复制,两者之间没有联系。通过复制来实现
|
|
2. 迭代
- what :如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration)。
- 这些可以直接作用于
for
循环的对象统称为可迭代对象:Iterable
- 集合数据类型:列表list、元组tuple、字典dict、字符串string、集合set
- generator,包括生成器和带
yield
的generator function
- 可以使用
isinstance()
判断一个对象是否是Iterable
对象
- 这些可以直接作用于
迭代操作
- list或tuple迭代
|
|
- 字典dict迭代
dict迭代的是key。
如果要迭代value,可以用for value in d.values(),如果要同时迭代key和value,可以用for key, value in d.items()。
|
|
- 字符串迭代
|
|
- 索引和元素同时迭代:Python内置的enumerate函数可以把一个list变成索引-元素对,这样就可以在
for
循环中同时迭代索引和元素本身:
|
|
判断迭代
- 判断是否可迭代:通过collections模块的Iterable类型判断
|
|
3. 列表生成式
- 将for循环和创建新元素的代码合并成一行;(语法糖)
|
|
字典推导式
12 > dict_result = { key-expr: value-expr for value in collection if condition} # 区别在与用 花括号>
>
集合推导式
12 > set_result = {expr for value in collection if condition}>
- 两层循环
|
|
4. 生成器
- what :一边循环一边计算的机制,称为生成器:generator。
如果列表元素可以按照某种算法推算出来,这样就不必创建完整的list,从而节省大量的空间。
- 创建生成器generator
- 只要把一个列表生成式的 [] 改成 (),就创建了一个generator:
|
|
创建
L
和g
的区别仅在于最外层的[]
和()
,L
是一个list,而g
是一个generatorgenerator保存的是算法,每次调用
next(g)
,就计算出g
的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration
的错误。
- 返回值
next()
函数获得generator的下一个返回值- 通过迭代
|
|
可以被next()
函数调用并不断返回下一个值的对象称为迭代器:Iterator
- 生成器都是
Iterator
对象,但list
、dict
、str
虽然是Iterable
,却不是Iterator
。- 把
list
、dict
、str
等Iterable
变成Iterator
可以使用iter()
函数:
- 把
|
|
list
、dict
、str
等数据类型不是Iterator
。因为Python的
Iterator
对象表示的是一个数据流,Iterator对象可以被next()
函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration
错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()
函数实现按需计算下一个数据,所以Iterator
的计算是惰性的,只有在需要返回下一个数据时它才会计算。
Iterator
甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。
类
面向过程 vs. 对象的程序设计
what :面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想。OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。
面向过程 vs. 对象编程:
- 面向过程的程序设计:把计算机程序视为一系列的命令集合,即一组函数的顺序执行。为了简化程序设计,面向过程把函数继续切分为子函数,即把大块函数通过切割成小块函数来降低系统的复杂度。
- 面向对象的程序设计:把计算机程序视为一组对象的集合,而每个对象都可以接收其他对象发过来的消息,并处理这些消息,计算机程序的执行就是一系列消息在各个对象之间传递。
在Python中,所有数据类型都可以视为对象。自定义的对象数据类型就是面向对象中的类(Class)的概念。
面向过程
|
|
- 面向对象
- 采用面向对象的程序设计思想,我们首选思考的不是程序的执行流程,而是Student这种数据类型应该被视为一个对象,这个对象拥有name和score这两个属性(Property)
|
|
创建 - 类
类是抽象的模板,比如Student类,而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法,但各自的数据可能不同。
类是创建实例的模板,而实例则是一个一个具体的对象,各个实例拥有的数据都互相独立,互不影响;
方法就是与实例绑定的函数,和普通函数不同,方法可以直接访问实例的数据;
通过在实例上调用方法,我们就直接操作了对象内部的数据,但无需知道方法内部的实现细节。和静态语言不同,Python允许对实例变量绑定任何数据,也就是说,对于两个实例变量,虽然它们都是同一个类的不同实例,但拥有的变量名称都可能不同:
class后面紧接着是类名,即Dog,类名通常是大写开头的单词,紧接着是(object),表示该类是从哪个类继承下来的,继承的概念我们后面再讲,通常,如果没有合适的继承类,就使用object类,这是所有类最终都会继承的类。
attribute为该类的属性;def 定义的该类的行为
|
|
__init__
: 初始化属性,此类方式在调用类时需传入外部参数有了init方法,在创建实例的时候,就不能传入空的参数了,必须传入与init方法匹配的参数,但self不需要传,Python解释器自己会把实例变量传进去:
self
:在类中定义属性,第一个参数永远是self,表示创建的实例本身。因此,在方法内部,就可以把各种属性绑定到self,因为self就指向创建的实例本身。即,将外部参数的属性传入到内部
创建 - 实例
因为类时一个抽象的概念,在创建具体的实例之前,必须先有一个容器;
|
|
访问
- 采用方法的方式来进行访问
|
|
- 限制访问
- 要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__,在Python中,实例的变量名如果以__开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问
|
|
改完后,对于外部代码来说,没什么变动,但是已经无法从外部访问实例变量.__name
和实例变量.__score
了:
|
|
- 获取限制访问的变量 :增加方法 - 给Student类增加get_name和get_score这样的方法
|
|
- 允许外部代码修改 : 增加方法 - set_score方法
|
|
需要注意的是,在Python中,变量名类似xxx的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是private变量,所以,不能用name、score这样的变量名。
有些时候,你会看到以一个下划线开头的实例变量名,比如_name,这样的实例变量外部是可以访问的,但是,按照约定俗成的规定,当你看到这样的变量时,意思就是,“虽然我可以被访问,但是,请把我视为私有变量,不要随意访问”。
修改属性
- 直接修改属性的值
|
|
- 通过方法修改属性
|
|
继承与重写
一个类继承另一个类时,会自动获得另一个类的所有属性和方法。原有的类:父类;新的类:子类;
- 创建子类时,父类必须包含在当前文件夹,且位于子类的前面
- 必须在括号内指定内类的名称
- 使用
super().__init__
将父类和子类关联起来,使其包含父类的所有属性
|
|
导入类
|
|
##主要函数
对象类型
- type() - 判断对象类型
- instance() - 判断一个对象是否为某种类型:返回布尔值Ture/Falses
|
|
能用type()判断的基本类型也可以用isinstance()判断
- 获得对象的所有属性与类型 - dir()
字符串操作
替换 - replace
|
|
分隔 - split - string转list
spilt - 通过指定的分隔符将字符串拆分为一组子串
- 字符串会转为列表list
|
|
去空格 - strip
strip - 去除空格(含换行符),相当于对各个元素执行x.strip()
|
|
联接 - join - list转string
join - 联接其他字符串序列的分隔符
- [列表转字符串]
|
|
其他
|
|
函数 VS. 方法
若为方法,也直接在符合的对象之后进行引用。
- DataFrame.xxx :数据框类型的对象
- datetime.xxx:时间类型的对象
函数
函数function —— A series of statements which returns some value toa caller. It can also be passed zero or more arguments which may beused in the execution of the body.
- 从定义的角度上看,函数(function)就相当于一个数学公式,它理论上不与其它东西关系,它只需要相关的参数就可以。所以普通的在module中定义的称谓函数是很有道理的。
- 函数是一段代码,通过名字来进行调用。它能将一些数据(参数)传递进去进行处理,然后返回一些数据(返回值),也可以没有返回值。所有传递给函数的数据都是 显式传递 的。
方法
方法method —— A function which is defined inside a class body. Ifcalled as an attribute of an instance of that class, the methodwill get the instance object as its first argument (which isusually called self).
- 方法,它是与某个对象相互关联的,也就是说它的实现与某个对象有关联关系。这就是方法。虽然它的定义方式和函数是一样的。也就是说,在Class定义的函数就是方法。
- 方法的定义可以是这样的,与某个对象进行绑定使用的函数。注意哦。绑定不是指” .”这个符号,这个符号说实在的只有域名的作用。绑定在这里是指,会默认赋值该绑定的对象。
- 方法也是一段代码,也通过名字来进行调用,但它跟一个对象相关联。方法和函数大致上是相同的,但有两个主要的不同之处:
- 方法中的数据是隐式传递的;
- 方法可以操作类内部的数据(请记住,对象是类的实例化 。类定义了一个数据类型,而对象是该数据类型的一个实例化)
- 从上面可以看出, 别的编程语言一样, Function也是包含一个函数头和一个函数体, 也同样支持0到n个形参,而Method则是在function的基础上, 多了一层类的关系, 正因为这一层类, 所以区分了 function 和 method.而这个过程是通过 PyMethod_New实现的
|
|
- 以本质上, 函数和方法的区别是: 函数是属于 FunctionObject, 而 方法是属 PyMethodObject
|
|
【Bound Method 和 Unbound Method】
method 还能再分为 Bound Method 和 Unbound Method, 他们的差别是什么呢? 差别就是 Bound method 多了一个实例绑定的过程!
A.f 是 unbound method, 而 a.f 是 bound method, 从而验证了上面的描述是正确的!
详细参见:https://segmentfault.com/a/1190000009157792
|
|
- 普通方法(老版中直接就是”instancemethod”)在module中与在Class中定义的普通函数,从其本身而言是没有什么区别的,他们都是对象函数属性。 之所以会被说在Class中的定义的函数被称为方法,是因为它本来就是面向将来的实例对象的,其实他们就是实例方法,这些方法是与实例相联系的(从实例出发访问该函数会自动赋值)。所以你从Class访问仍然是一个函数
- 类方法(”classmethod”),因为类同样是对象,所以如果函数与类进行联系了话(与实例方法一样的模式)那么就能够这么说了!
- 静态方法,虽然定义在内部,并且也较方法,但是却不与任何对象联系,与从类访问方法是一样的,他们仍然是函数。
【实战演练】
for循环
|
|
打开与写入
|
|