一、公共方法的学习:
(1)对于字符串的切片(也可用于list、tuple):
格式为:str[起始index:结束index:步长]
例如,str[0:6:2],截取索引0到6间的数字,步长为2,则取出了索引为0,2,4的数据。
起始index包括,结束index不包括在内。若是不写明,起始默认为0,结束默认为len(str),步长默认为1
例如,str[:]表明截取全部。不特意表明步长,第二个冒号可以省略。
(2)list的append方法和extend方法的区别:
append方法添加一个list2到list1中,list2是作为一个整体元素保存的
extend方法添加一个list2到list1中,是将list2中的元素提取再保存到list1
(3)+和 * (字符串、列表、元组)
in/ not in(字符串、列表、元组、字典) 的使用
+:将两个元素进行合并
*:重复合并 例如['1']*3 得到['1','1','1']
in:返回是否含有某个值(true/false) 例如: A = ‘0’ in ['0','1']
not in :同理。
(4)完整for循环的学习:
for 变量 in 集合:
循环体代码
else:
没有通过brea退出循环时,完成了完整循环后,执行的代码段
若循环体中有break就退出循环,如果没有break,就在循环体代码执行完成后执行else下的代码段
应用场景:在所有搜索完成后没有找到自己所需就可以利用
(5)注释的使用:
在实际开发中,借助TODO注释,可以更好的帮助开发者完成开发。
标注方式为: # TODO 需要做的事
这样标记完成后,可以在PyCharm的左下角进行选择。开发过程中可以查看自己未完成部分。
函数注释:PyCharm中,将光标放置到函数定义的函数名上,然后点击小灯泡,点击Insert documentation string stub。即可添加,然后根据内容进行补充。
实际开发中,有效的注释可以帮助我们更好的阅读代码,理解代码。
(6)变量、参数的学习:
①函数参数的传入实际上是形参,对实参的【引用】,传入的是实参的地址,而非数据。
②数据分为可变型和不可变型:(内存中数据是否可以修改)
可变:列表、字典(字典的key只可以使用不可变类型)
修改时只改变数据,不改变存储数据的地址
不可变:字符串、数字(int、float等)、元组
③全局变量:
全局变量应该置于其他函数上方,取名规则:最好前缀加上g_或是 gl_
python中,函数内部不允许直接改变全局变量的值,若是直接赋值,实际上是新定义了一个局部变量
如果需要在函数内部改变全局变量,可以使用 global关键字进行申明再修改
例如:global 全局变量;全局变量=修改值
局部变量:
函数内部改变局部变量,若是可变型数据:外部数据也会被修改;若是不可变类型数据:外部不会改变!
④参数:
具有默认值的参数就是缺省参数。
缺省参数的定义:
def pr_info(name,gender = True): #在定义时定义一个默认值,最好使用最常用的值。!需要保证缺省参数在参数的末尾!
gender_text = 'male'
if not gender:
gender_text = 'female'
print(name+gender_text)
pr_info('dd',False)
在开发时由于有些函数的参数个数不确定,所以产生了多值参数!
多值参数有两种:
参数名前增加一个*表示可以接收元组:例如*args
参数名前增加两个*表示可以接收字典:例如**kwargs
使用:
def demo(num,*args,**kwargs):
print(num)
print(args) #注意使用时不是*args
print(kwargs)
demo(1,2,3,4,name='tt')
得到结果:
1
(2, 3, 4)
{'name': 'tt'}
元组、字典拆包:
这种操作是由于以下情况:
def demo(*args,**kwargs):
print(args)
print(kwargs)
gl_args = (1,2,3)
gl_kwgras = {'name':'tt'}
demo(gl_args,gl_kwgras)
得到的结果是:
((1, 2, 3), {'name': 'tt'})
{}
所以需要进行拆包:
demo(*gl_args,**gl_kwgras)
即可得到正常结果:
(1, 2, 3)
{'name': 'tt'}
(7)递归(函数内部自己调用自己):
在函数内部自己调用自己,且需要有递归出口,在满足一定条件时退出循环。
二、面对对象编程:
类、对象、属性、方法等概念不再阐述,与其他编程语言类似。
(1)方法:
python中对象无处不在,变量、数据、函数都是对象。
而对象所对应的方法列表和属性可以通过以下方式进行查看:
①标识符/数据后 按. 然后按tab键可以得到一个方法list
②用dir()函数传入标识符/数据,可以查看其所有方法和属性
例如python内置的方法:
__new__ / __init__/ __del__/__str__ 在应用场景中会被自动调用
①类在新建对象时会自动调用python内置的__init__方法来进行初始化
假如需要更改新建对象的初始化属性,可以在新建对象时传入参数,传入的参数传入到了__init__方法进行处理
②需要在退出该对象时自动调用执行某些操作,可以借助__del__方法
③希望使用print函数打印对象的内部信息,可以借助__str__ 方法将内部信息return出来。打印对象时就会执行
例如:若没使用该方法:print(对象名)得到的是该对象的地址
使用后:得到的是__str__方法中想打印的信息
(2)类与对象:
新建一个类的对象,变量名 = 类名() :例如 Tom = Cat()
实际上是使用类新建了一个对象后,用变量来引用这个对象的地址。
想在类外部添加新的属性,直接使用赋值语句即可。(不修改类,直接给对象添加属性)例如:class.newd = 'ddd' 但是开发时并不推荐这种做法
想将一个类作为另外一个类的属性,直接使用赋值语句即可。
类是一个特别的对象!也有属于自己属性和方法,分配了方法,只有一份,但一个类会有多种对象实例。例如开发时想统计某一个类生成了多少个对象,就可以在初始化方法中设计统计数,每调用一次初始化方法就计数1,从而得到生成对象总数。这个设置的数值就是属于类的属性。
类名.类属性名 可以访问
对象名.类属性 也可以访问,但是不推荐。这是因为python中属性有向上查找的机制。
不推荐的原因是: 对象.类属性 = 值 赋值语句会给对象添加一个属性,而非改变类属性的值
类方法的定义:
@classmethod
def 类方法(cls):
pass
需要添加关键字@classmethod 其中的cls就如同实例方法中的self一样,默认为谁调用这个方法就是谁。
类的内部:可以使用cls.类方法调用其它类方法/cls.类属性 来进行访问属性
类中封装一个方法,若这个方法不需要访问实例属性/方法也不需要访问类的属性/方法,这时把这个方法封装为静态方法
静态方法的定义:
@staticmethod
def 类方法(cls):
pass
静态方法和类方法的调用是一样的。
区分:
实例方法 ----方法内部需要访问实例属性或者实例属性+类属性
类方法 ---- 方法内部只需要访问类属性
静态方法 ---- 方法内部不需要访问实例属性和类属性
(3)运算:
is和==的区别:
is用来判断两个引用的地址是否一致,而==用于判断两个值是否一致。
面向对象开发三大特性:
封装:根据功能将属性和方法封装到一个抽象的 类 中
继承:实现代码的重用,重复的代码不用重新编写
多态:不同的子类对象调用相同的父类方法,得到不一样的结果
(4)封装:
定义一个类的属性都在内置的__init__()方法中进行
(5)继承:
单继承:一个子类拥有一个父类 定义:class 子类(父类)
多继承:一个子类拥有多个父类,具有所有父类的信息。定义:class 子类(父类1,父类2)
如果父类间有同名属性或方法应该谨慎使用多继承。
继承后的访问:
①子类访问父类的属性和方法:子类.属性/方法
②子类重写同名属性/方法:直接在子类中编写即可,调用时即调用子类中的
③子类需要在父类原有方法基础上扩展:新建之后若需要用到父类的原属性/方法:super().父类方法
多继承中如果父类1/2都含有某种属性/方法,子类调用时调用的是先继承的。(并不建议这种情况使用多继承)
Tips:在python中为类内置了一个__mro__属性,用于查看方法搜索顺序。
查找到就执行,否则继续查找到下一个类,若全无则报错
例如:c=C() print(C.__mro__)可以得到:
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
其中C多继承于A B,object类是所有类的基类。
python3.*版本中如果没有指定父类则默认以object为基类,这种以object为基类的类也称为新式类,否则称为旧式(经典)类。
python2.*版本中未指定父类不会以object类为基类。这种新旧的区别在多继承中会影响到搜索顺序。所以为了程序能在多个版本运行,定义类时若没有父类建议自行继承object 类。
class 类名(object)
pass
(6)多态
不同的子类对象调用相同的父类方法得到的结果不同。还取决于调用父类本身的子类对方法的扩展、覆盖以及属性的改变。
(7)new方法的学习
_new_方法是object基类提供的内置的静态方法,调用时要主动传递cls参数,其作用有:
①在内存中为对象分配存储空间②返回对象的引用
当用类名创建一个新的类时,python的解释器会先调用_new_方法为对象分配空间
python解释器获得引用后将其作为第一个参数传递给_init_方法。所以在重新_new_方法时,必须return super()._new_(cls)否则不能传递引用
(8)单例设计模式
让类创建的对象,有且仅有一个实例,每次执行类名返回的地址是一定的。
实现方法:
①定义一个类属性初始化为None,用于记录单例对象的引用
②重写_new_方法
③如果该类属性为None则调用父类方法分配空间,并修改类属性
④返回类属性中的对象引用
例如:
instance = None
def __new__(cls, *args, **kwargs):
# 1.判断类属性是否是空对象
if cls.instance is None:
# 2.没有创建则调用父类方法分配空间
cls.instance = super().__new__(cls)
# 3.返回类属性保存的引用空间
return cls.instance