选择与循环
字符串
.format()函数使用中,{}中的格式控制标记顺序分别为:填充—>对齐—>宽度—>,—>.精度—>类型
1
2
3
4
5
6table = ''.maketrans('abcdef123', 'uvwxyz@#$')
s = "Python is a greate programming language. I like it!"
#按映射表进行替换
s.translate(table)
'Python is u gryuty progrumming lunguugy. I liky it!'
正则表达式
正则表达式使用某种预定义的模式去匹配一类具有共同特 征的字符串,主要用于处理字符串,可以快速、准确地完 成复杂的查找、替换等处理要求,在文本编辑与处理、网 页爬虫之类的场合中有重要应用。
函数的设计和使用
首先了解到Python变量名和它的值是一个类似字典的键值对关系,不同的命名空间可以看作不同的字典,我们在使用变量的时候调用规则是LEGB规则,查找使用一个变量,顺序为L-E-G-B,可以理解顺序查找这几个字典中有没有我们使用的变量名,有则调出使用该变量名映射的值,没有则按照顺序向上一级寻找,除非声明global或者noglobal,这样我们就将这个变量声明到了global或者noglobal字典中,同时调用
Python面向对象程序设计
基础概念类(Class)是用来描述具有相同属性(Attribute)和方法(Method)对象的集合。
属性(Attribute): 类里面用于描述所有对象共同特征的变量或数据。比如学生的名字和分数。
方法(Method): 类里面的函数,用来区别类外面的函数, 用来实现某些功能。比如打印出学生的名字和分数。
创建类时用变量形式表示的对象属性称为数据成员,用函数形式表示 的对象行为称为成员方法,成员属性和成员方法统称为类的成员。
属性是指一种从现实中抽象出来的某种事物的属性,但是实现在变量和函数上
python面向对象语法中的特别点
1、pass关键字
Python提供了一个关键字“pass”,类似于空语句,可以 用在类和函数的定义中或者选择结构中。当暂时没有确定 如何实现功能,或者为以后的软件升级预留空间,或者其 他类型功能时,可以使用该关键字来“占位”。
因为python中没有大括号来区别各种结构,所有我们只能使用pass来代表空结构
2、构造函数
构造函数名称均为__init__
3、 self参数和cls参数self表示一个具体的实例本身
cls表示这个类本身
类的所有实例方法都必须至少有一个名为self的参数,并且必须是方法的第一个形参(如果有多个形参的话), self参数代表将来要创建的对象本身。
在外部通过对象调用对象方法时并不需要传递这个参数, 如果在外部通过类调用对象方法则需要显式为self参数传值。1
2
3
4例如
test1=Test()
test1.testP()
Test.testP(test1)
4、类变量和实例变量的定义类变量:定义在类中且在函数体之外。类变量在所有的实例变量中是共享的类似于静态变量
实例变量:定义在实例方法中的变量。一般的实例变量我们设置在构造函数里,当然也可以在其他函数体中创建
实例变量的定义必须为sefl.变量名=,若直接使用变量名=则为函数内的局部变量,在类方法中定义的cls.变量名=是类变量
访问实例变量也需要self.变量名
5、实例方法和类方法和静态方法实例方法:只能通过实例对象调用,因为实例方法第一个定义的参数必须是实例对象本身self。
类方法:定义类方法,要使用装饰器@classmethod,定义的第一个参数一般是cls,代表这个类本身,
静态方法:定义静态方法使用装饰器@staticmethod,没有默认的必须参数,可以通过类和实例直接调用。
self和cls是我们的默认名称比较统一,也可以使用其他名称,但是在python语言的特性下,是不过是我们表面上换了个名字而已
类方法和静态方法区别:类方法自带参数cls代表本身类,而静态方法不带参数。所以在函数体中使用类的变量的区别就是类方法可以以cls调用这个类的属性,而静态方法需要以类名去调用,相当于是一个类外函数1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20class (object):
a = 'a'
@staticmethod
def foo1(name):
print ('hello', name)
print (A.a) # 正常
print (A().foo2('mamq'))
def foo2(self, name):
print ('hello', name)
@classmethod
def foo3(cls, name):
print ('hello', name)
print (A.a)
print (cls().foo2(name))
A.foo1("lyxf")
A.foo3("lyxf")
输出结果相同
由于python的特性其中中没有public、static 这样的修饰符,[email protected]
6、可动态为自定义类和对象增加或者删除成员
动态添加对象属性
针对对象动态添加的属性,是绑定在该对象身上的,在同类其他对象上是没有的的。
动态添加类属性
针对类动态添加的属性,可以增添到使用到所有的该类创建的对象上
由于动态语言的特性,哪怕你是后添加的类属性,之前创建的对象也会增加新的类属性
动态添加对象行为
如果直接添加,调用的时候需要将本身的对象作为参数传入1
2
3
4
5
6
7
8class Demo:
pass
t = Demo()
def test(self,a):
print(a)
t.test=test
t.test(t,3)
#结果为输出3
而特殊的1
2
3
4
5
6
7
8class Demo:
pass
t = Demo()
def test(a):
print(a)
t.test=test
t.test(3)
#结果为输出3
虽然可执行,但是是因为我们没有使用self,如果增加一个函数中定义实例变量就必须使用self,而且这样也不符合类中的定义方法的习惯所以一般不要使用
而我们想不传入对象参数,可以使用types模块的MethodTpye功能1
2
3
4
5
6
7
8
9
10import types
class Demo:
pass
t = Demo()
def test(self,a):
self.value=a
print(self.value)
t.test=types.MethodType(test,t)
t.test(3)
#结果为输出3
动态添加类行为
同理我们为类动态添加行为1
2
3
4
5
6
7
8
9
10
11import types
class Demo:
pass
t = Demo()
def test(cls,a):
cls.value=a
print(cls.value)
Demo.test=types.MethodType(test,Demo)
Demo.test(3)
t.test(3)
#输出为两行3,动态增加了类方法
而使用del 可以动态删除类中或者对象的各种属性1
2
3例如:
del Test.d
del Test.func
注意方法只能通过类名+方法名删除,不能通过对象删除,实例变量只能通过对象删除
7、私有成员、保护成员与公有成员
类里面的私有属性和私有方法以双下划线__开头。私有属性或方法不能在类的外部被使用或直接访问。
类里面的保护属性和保护方法以单下划线_开头。不能用于 from module import *
公有成员则不加下划线
这里特别指出两边都加双下划线是一些特殊函数,如构造函数、析构函数等
注意:保护成员可以直接修改1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18class Test:
__a="类私有"
_b="类保护"
d="类公有"
def __init__(self):
self._c = "实例保护"
def __testPrivate(self):
print(self.d)
t1=Test()
print(t1._c)
print(Test._b)
t1._c="实例保护更改"
print(t1._c)
#输出为
#实例保护
#类保护
#实例保护更改
9、Python中不存在严格意义上的私有成员
对象外部可以通过“对象名._类名__xxx”这样 的特殊方式来访问1
2
3
4
5
6
7
8
9
10
11
12
13
14class Test:
__a="类私有"
_b="类保护"
d="类公有"
def __init__(self):
self._c = "实例保护"
self.__d="实例私有"
t=Test()
print(Test._Test__a)
#这里使用对象名._类名__xxx代表通过t使用类私有变量,若为类名._类名__xxx则代表通过类使用类私有变量
print(t._Test__d)
#输出为
#类私有
#实例私有
可以理解为Python私有保护机制只是识别后给我们内部“改了名”,在前面增加了单下划线+类名,同理可以使用对象名._类名xxx直接调用私有方法
10、property的使用完善封装机制
(1)@property和setter、getter修饰器
(2)property函数1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22class Test:
def __init__(self, value):
self.__value = value
def __get(self):
return self.__value
def __set(self, v):
self.__value = v
def __del(self):
del self.__value
value = property(__get, __set,__del)
def show(self):
print(self.__value)
t=Test(5)
t.show()
t.value=10
t.show()
print(t.value)
del t.value
#输出为
#5
#10
#10
修改、读取、删除,需要几种对值的权限操作就在property函数相应顺序(读->写->删)放置对应函数
我们要理解,使用get,set方法,而不是直接赋值,是因为能在方法中进行各种设值的限制,因为python的特性,动态添加和修改可以修改成任意类型任意大小的值,很容易出错,使用方法可以通过控制语句在其中添加限制条件,选择出符合要求的值进行添加。而property的使用使得这个方法能够想变量一样简单使用
常用特殊方法
值得注意的是运算符重载就是通过重写特殊方法实现的
继承和多态机制
1、定义继承类1
2
3
4
5
6
7class TestParent:
def __init__(self,name):
self.name=name
class Test(TestParent):
pass
test=Test("parent")
print(test.name)
在定义的类名后加括号依次写入父类,Python支持多继承
2、多态实现
根据继承特性:私有成员不会被继承
公有成员会被继承,在子类中重写父类的方法,调用子类的对象时会使用重写的方法
若子类无构造函数则继承父类构造函数,若有则使用该构造函数而不使用父类的
如果需要在派生类中调用基类的方法,可以使用内置函数 super()或者通过“基类名.方法名()”的方式来实现这一目的。。
3、多继承机制如果父类中有相同的方法名,而在子类中使用时 没有指定父类名,则Python解释器将从左向右按顺序进行搜索,找到第一个后边不再向后解析
在Python 3.x的多继承树中,如果在中间层某类有向上一 层解析的迹象,则会先把本层右侧的其他类方法解析完, 然后从本层最后一个解析的类方法中直接进入上一层并继 续解析,也就是在从子类到超类的反向树中按广度优先解析