(一)面向对象
类:用来描述具有相同属性和方法的对象的集合
一. 类的命名方式
- 大驼峰 首字母大写
- 见名知意
- 区分大小写
类的实例:
class Women: sex = '女' faceValue = '高' height = '168' weight = '85斤' color = 'yellow' def makeMoney(self): print("可以赚钱") def cooking(self): print("做饭") print(Women) # <class '__main__.Women'>
二 . 对象
类的实例化为对象
object = 类名([参数])
实例:
lisi = Women() # 将Women类实例化成对象 print(lisi) # <__main__.Women object at 0x0000007524346A90>
三. 属性和方法的使用
object.属性名 # 调用属性
object.方法名() # 调用方法
注意:类里面的变量称之为属性 类里面的函数称之为方法
四. self的说明
方法里面的self代表的是当前类的实例化后的对象
self不是只能叫self, 别的也可以, 但是规范来说 都是用self
实例:
class A: name = '' def demo(self): print(self) # self 代表当前实例化类的对象 # print(id(self)) a = A() a.demo() # # <__main__.A object at 0x000000C22C4B8358> print(a) # <__main__.A object at 0x000000F74F008358> b = A() b.demo() # <__main__.A object at 0x0000009EE9756860> print(b) # <__main__.A object at 0x000000EA38296860>
五. return - 方法的返回值
和函数一样 代码遇到return 下面就不在执行 会将值返回给调用处
没有return的方法 打印调用处的值为None
实例:
class Demo: name = '' def speak(self): print("我是{}号类".format(self.name)) def myReturn(self): return self.name # print(self.name) # 不在执行 d2 = Demo() # print(d2.name) # '' d2.name = 'd2' # 给当前对象 添加对象属性 d2.speak() # 我是d2号类 print(d2.speak()) # None d2Name = d2.myReturn() print(d2Name) # 返回值 d2
六. 对象属性和类属性
- 使用对象创建的属性称之为对象属性,对象属性只有在当前对象里才存在
- 如果使用对象属性创建了一个和类属性里面同名的属性,那么调用的时候会优先查找对象里面的属性
- 使用类里面的方法的参数self创建的属性也为对象属性
- 当使用对象.属性名 来改类里面的属性的时候,其实是在对象里面创建了一个同名的对象属性
- 当将对象里面的同名的属性删除掉以后,还是会调用类的属性(当对象属性存在时找对象属性,对象里不存在,找类属性)
- 不能在对象里 删除类里面的属性 只有使用的权利
- 使用类操作过的属性 所有对象在调用类属性的时候 都是修改后的属性
实例:创建对象属性的方法:
# 法一: class A: pass a = A() a.name = 'xxx' # 创建对象属性 对象名.属性名 # 法二: class A: def createVal(self): self.name = 'oo' a = A() a.createVal() # 创建对象属性
创建类属性的方法:
# 类名.属性名 A.name = '张三'
七. 给对象绑定方法
(1) 给对象绑定方法
from types import MethodType
实例:
from types import MethodType class A: pass def func(self): # 类外的函数 print("xxxxxxxxxx") a = A() a.func = MethodType(func, a) # 用MethodType将方法绑定到类的对象 MethodType(方法名,对象名) a.func() # 调用 a.func = func #或者用这种方法 a.func(a)
(2) 给类绑定方法
def func(self): print('func') # 类名.属性名(函数名) = 函数名 A.func = MethodType(func,A)
注意:
- 给对象绑定属性或者方法 只有当前对象有
- 给类绑定属性或者方法 所有当前类的实例化的对象都会拥有
八. __slots__限制对象动态添加属性
如果我们想要限制class的属性怎么办?比如,只允许对Student实例添加name
和age
属性。
为了达到限制的目的,Python允许在定义class的时候,定义一个特殊的__slots__
变量,来限制该class能添加的属性:
>>> class Student(object):
... __slots__ = ('name', 'age') # 用tuple定义允许绑定的属性名称
...
然后,我们试试:
>>> s = Student() # 创建新的实例
>>> s.name = 'Michael' # 绑定属性'name'
>>> s.age = 25 # 绑定属性'age'
>>> s.score = 99 # 绑定属性'score'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute 'score'
由于'score'
没有被放到__slots__
中,所以不能绑定score
属性,试图绑定score
将得到AttributeError的错误。
使用__slots__
要注意,__slots__
定义的属性仅对当前类起作用,对继承的子类是不起作用的:
>>> class GraduateStudent(Student):
... pass
...
>>> g = GraduateStudent()
>>> g.score = 9999
除非在子类中也定义__slots__
,这样,子类允许定义的属性就是自身的__slots__
加上父类的__slots__
。
九. 私有属性和私有方法
(1) 类的私有属性以__两个下划线作为开头,不能在类外进行使用和访问,在类的里面使用self.__属性名
私有属性的访问:
在类的外部: 对象._类名__属性名 进行查找
在类的内部: 通过方法里面的变量self.__属性名 进行调用
注意:在类的内部只要使用self.__属性名 就会去找私有属性 也就是__类名__属性名
(2) 类的私有方法:以__作为开头 不能在类的外部进行使用和访问 在类的里面使用 self.__方法名
在类的公有方法里面 通过self.__方法名调用
(二)继承
概念: 面向对象编程带来的最大的好处就是代码的重用 实现代码重用的操作就是类的继承
被继承的类被称为 父类(基类)或超类
继承的类称之为子类
所有的类都是继承自一个超类object
(1) 单一继承
class 类名(继承的父类):
pass
实例:
class A: # 不管是本类还是子类 只要实例化 就会调用(如果子类重写了Init函数子类实例化对象会覆盖父类的init函数) def __init__(self,name,age,sex): # print("一旦实例化就会自动调用 ") self.name = name self.age = age self.sex = sex def speak(self): print('我现在{}岁了 我叫{},我的性别是{}'.format(self.age,self.name,self.sex)) # a = A('张三',19,'男') # print(a.name) # 张三 #cla.speak() class B(A): # grade = '' def __init__(self): print("我是子类的") # A.__init__(self,'张三',19,'男') pass # b = B() # 如果子类没有重写父类的init的方法,会自动调用父类的init的方法 # b.sex # 如果没实现子类的构造方法 会报 error 找不到 没有对父类进行初始化 class C(A): grade = '' def __init__(self,name,age,sex,grade): print("我是子类的init函数") self.grade = grade A.__init__(self,name,age,sex) def speak(self): A.speak(self) # 调用父类的speak print("我今年{} 我叫{} 我的成绩是{}".format(self.age,self.name,self.grade)) c = C('张三',13,'男',69) # print(c.name) # 父类的张三 # print(c.__dict__) # {'grade': 69, 'name': '张三', 'age': 13, 'sex': '男'} c.speak()
注意:
- 类的单一继承 子类会继承父类私有以外的全部属性和方法
- 如果在子类里存在和父类同名的属性和方法 叫做方法或属性的重写(也就是会覆盖掉),再次调用的时候回调用子类的方法或属性
- 在子类里调用父类的方法 通过 类名.方法名(self,[参数…]) self代表当前类的实例化对象
- super(当前类名,当前self).方法名 (如果是单一继承super方法不建议加参数)
(2) 多继承
class 类名(继承的父类1, 继承的父类2,[父类3..])
pass
注意:
- 当类进行多继承的时候 注意父类的顺序 当父类存在同名的属性或者方法的时候,会从继承的父类从左到右依次查找,使用第一个父类的属性或者方法
调用父类的方法:
class A: def speak(self): print("我是A类的speak方法") def a(self): print('a') class B: def speak(self): print("我是B类的speak方") def b(self): print('b') class C(A, B): def speak(self): # super().speak() # 还是从左往右找 我是A类的speak方法 # super(C,self).speak() # 传入当前类名 从左往右找 我是A类的speak方法 super(A,self).speak() # 找A后面的B 我是B类的speak方 # super(B,self).speak() # 找B后面 没有 报错 c = C() c.speak() # c.a() # c.b()
二. 常用的属性
__doc__
类的说明__name__
返回类名__base__
返回一个父类__bases__
返回多个父类__dict__
以字典的形式返回对象或者类的信息
三. 静态方法(不用传self的方法)
@statimethod
可以在类的实例化成对象来调用 也可以使用类名来调用
实例:
class A: @staticmethod def demo(): # 静态方法 print("类来调用") a = A() # a.demo() # 如果没加staticmethod ,会报TypeError,没给方法写上self参数, A.demo() # ok a.demo() # 加上staticmethod 之后 ok
四. 魔术方法
__init__
构造方法 作为类的初始化__del__
析构方法 在当前文件执行完毕之前去执行 或者有时候用del 对象名 触发__str__
用于转换为人能够阅读的形式__repr__
转换为解释器查看的形式__add__
运算符重载__getattr__
调用不存在的属性的时候会触发__len__
返回集合中所含元素的数量__getitem__
返回与所给键对应的值__setitem__
按一定的方式存储和key相关的value