对象
对象是指现实中的物体或实体
面向对象
把一切堪称对象(实例),让对象和对象之间简历关联关系
对象都有什么特征:
属性(名词):姓名,年龄,性别,颜色… … …–>变量
行为(动作):学习,吃饭,睡觉,踢球… … …–>方法
什么是类:
用于相同属性和行为的对象分为一组,即为一个类
类是用来描述对象的工具,用类可以创建同类对象
Python类名最好使用驼峰命名法:
Mylist MyRange 大驼峰(所有单词首字母大写)
getStudentAge 小驼峰 (第一个首字母小写,其余大写)
说明:因为python内置类为小写,防止命名冲突
类的创建语句:
语法:
class 类名(继承列表):
'''类的文档字符串'''
实例方法定义(类内的函数称为方法method)
类变量定义
类方法定义
静态方法定义
类 | 对象 实例
class | object instance
表达式:
类型([创建传参列表])
作用:
创建这个类的实例对象,并返回此实例对象的引用关系
示例:
class Dog: #Dog是一个变量,绑定一个类
pass
dog = Dog() #dog绑定一个对象
实例方法:
语法:
class 类名(继承列表):
def 实例方法名(self,参数1,参数2,...):
'''实例方法的文档字符串'''
语句块
实例.实例方法名(调用传参)
或
类名.实例方法名(实例,调用传参)
实例:
#此实例用来定义一个学生类,并实现添加信息和打印信息的功能
class Student:
def set_info(self,name,age):
'''此方法用来给对象添加姓名和属性'''
self.name = name
self.age = age
def shou_info(self):
print(self.name,'今年',self.age,'岁')
#定义一个Student对象并调用方法
s1 = Student()
s1.set_info('小王',24)
s1.show_info()
语法:del 对象.实例变量名
示例:
c1 = Cat()
c1.color = '白色' #添加属性
print(c1.color)
del c1.color #删除属性
print(c1.color) #属性错误
语法格式:
class 类名(继承列表):
def __init__(self[,形参列表]):
语句块
说明:
1.初始化方法名必须为__init__不可改变
2.初始化方法会在构造函数创建实例后自动调用,且将实例自身
通过第一个参数self传入__init__方法
3.初始化方法内部如果需要返回则只能返回None
示例:
#此示例示意__init__方法的自动调用及添加实例变量
def Car:
def __init__(self,c,b,m):
print('__init__方法被调用')
self.color = c #颜色
self.brand = b #品牌
self.model = m #型号
a4 = Car('黑色','奥迪','A4')
a4.__init__('黑色','奥迪','A4') #显式调用
#__init__方法具体步骤:
#1.创建一个没有属性的对象
#2.把这个对象传递给__init__方法
#3.引用关系传递给A4
语法:
class 类名(继承列表):
def __del__(self):
语句块
示例:
class Car:
def __init__(self,name):
self.name = name
print('汽车',name,'对象已创建')
def __del__(self):
print(self.name,'对象已被销毁')
car1 = Car('奔驰 E6')
#程序结束会自动调用__del__方法
__dict__属性
此属性绑定一个存储此实例自身变量(属性)的字典
示例:
class Dog:
pass
dog1 = Dog()
print(dog1.__dict__) #{}
dog1.color = '白色'
print(dog1.__dict__) #{'color':'白色'}
#键值对赋值
dog1.__dict__['age'] = 3
__class__属性
此属性用来绑定创建此实例的类
作用:
可以借助此属性来访问创建此实例的类
dog2 = dog1.__class__() #等同于dog2 = Dog()
isinstance(obj,class_or_tuple)
#返回这个对象obj是否某个类class或某些类的实例,如果时则返回
#True,否则返回False
#实例:
animal = Dog()
isinstance(animal,(Cat,int)) #返回False
isinstance(aninal,(Dog,int)) #返回True
Type(obj) #返回对象的类型
示例:
#此示例示意类变量的定义和使用
class Human:
count = 0
print('Human的类变量count=',Human.count) #0
Human.count = 100
print(Human.count) #100
#以下示意类变量与示例变量的区别及示例间接访问类变量
h1 = Human()
h1.count = 200
print(h1.count) #200
print(Human.count) #100
h1.__class__.count +=200
print(h1.count) #200
print(Human.count) #300
#用类变量记录对象的个数
class Car:
count = 0 #创建类变量,用来记录汽车对象总数
def __init__(self,info):
print(info,'被创建')
self.data = info
self.__class__.count+=1 #让汽车的总数加1
def __del__(self):
print(self.data,'被销毁')
#当车被销毁时总数自动减1
self.__class__.count -= 1
print('当前汽车总数是:',Car.count)
b1 = Car('BYD 京A.88888')
print('当前汽车总数是:',Car.count)
b2 = Car('TESLA 京B.88888')
print('当前汽车总数是:',Car.count)
del b1
print('当前汽车总数是:',Car.count)
类的文档字符串
类内第一个没有赋值给任何变量的字符串是类的文档字符串
说明:
类的文档字符串用类的__doc__属性可以访问
类的文档字符串可以用help()函数访问
类的__slots__列表
作用:限定一个类的实例只能有固定的属性(实例变量)
通常为当错写属性名时不添加属性而是发出报告
说明:
含有__slots__列表的类创建的实例对象没有__dict__属性,
即此实例不用字典来保存对象的属性(实例变量)(因为字典为可变的而__slots__限制了不可变)
示例:
#此示例示意类的变量__slots__列表的作用
class Student:
__slots__ = ['name','score'] #限制类只拥有这两个属性
def __init__(self,name,score):
self.name = name
self.score = score
s1 = Student('小李',68)
print(s1.score)
s1.scrce = 100 #此处错写了属性名,若无__slots__列表将不会报错
print(s1.score)
print(s1.__dict__)#发生AttributeError,此对象没有__dict__属性
示例:
#此示例示意类方法的使用
class Car:
count = 0 #类变量
@classmethod
def getTotalCount(cls): #传参业内规定写cls
'''此方法为类方法,得到类变量'''
return cls.count
@classmethod
def updateCount(cls,number):
'''此方法为类方法,更新类变量'''
cls.count+=number
print(Car.getTotalCount()) #用类来调用类方法
#Car.count +=1 #面向对象思想不提倡直接操作属性
Car.updateCount(1)
print(Car.getTotalCount()) #1
c1 = Car() #创建一个对象
c1.updateCount(100) #Car类的示例也可以调用类方法 实际上
#相当于把c1.__class__传入cls参数
print(c1.getTotalCount()) #101
c2 = Car()
c2.count = 200 #实例属性
print(c2.getTotalCount()) #200,类方法不能访问实例的属性
示例:
#此示例示意静态方法的创建和使用
class A:
@staticmethod
def myadd(a,b):
'''此方法为静态方法
此方法的形参不需要传入类和实例'''
return a+b
print('1+2 = ',A.myadd(1,2)) #类调用
a = A() #对象调用
print('100+200 = ',a.myadd(100,200))
class 类名(基类名):
语句块
说明:单继承是指派生类由一个基类衍生出来的类
示例:
#此示例用来示意继承和派生
class Human:
'''此类用来描述人类的共性行为'''
def say(self,word):
print('say',word)
def walk(self,distance):
print('走了',distance,'公里')
class Student(Human):
'''学生类单继承Human类并派生新的方法'''
def study(self,subject):
print('正在学习',subject)
s1 = Student()
s1.say('今天天气真好')
s1.walk(5)
s1.study('Python')
示例:
class Human:
pass
class Student(Human):
pass
class Teacher(Student):
pass
t1 = Teacher()
t1.__base__ #Student
t1.__base__.__base__ #Human
Human.__base__ #object
object.__base__ #None
#示意bool的基类
True.__base__ #bool
True.__base__.__base__ #int
int.__base__ #object
示例:
class A:
def work(self):
print('A.work()被调用')
class B(A):
def work(self):
print('B.work被调用') #覆盖父类方法
b = B()
b.work()
b.__class__.__base__.work(b) #虽然覆盖子类也能调用父类的方法
super(type,obj)返回绑定超类的实例
super() 返回绑定超类的实例,等同于:(必须在子类方法内调用)
super(__class__,实例方法的第一个参数)
示例:
class A:
def work(self):
print('A.work被调用')
class B(A):
def work(self):
print('B.work被调用')
def super_work(self):
#super(B,self).work() #A.work()
#super(__class__,self).work() #A.work()
super().work() #A.work()必须在方法内调用
b = B()
b.super_work() #A.work()
示例:
class Human:
def __init__(self,n,a):
self.name = n
self.age = a
def info():
print('姓名:',self.name)
print('年龄:',self.age)
class Student(Human):
def __init__(self,n,a,s):
super().__init__(n,a)#使用super显式调用基类初始化方法
self.score = s
def info(self):
super().info()
print('成绩:',self.score)
s1 = Student('小王',23,100)
s1.info()
isinstance(obj,cls)
判断对象obj是否是cls的对象,若cls是obj的类或父类则返回True
否则返回False
issubclass(cls,class_or_tuple)
判断一个类cls是否继承自class_or_tuple,返回True或False
查看python内建类继承关系的方法:
help(__builtins__ )
示例:
class A:
pass
class B(A):
pass
class C(B):
pass
issubclass(C,(A,B)) #True
issubclass(C,object) #Ture
示例:
class A:
def __init__(self):
self.__p1 = 100 #__p1为私有属性,在外部不可访问
def test(self):
print(__p1)
self.__m1() #A类的方法可以调用A类的私有方法
def __m1(self): #__m1为私有方法
print('m1方法被调用')
a = A()
print(a.__p1) #在类外看不到__p1属性,访问失败!
a.test() #使用方法访问私有属性
a.__m1() #调用失败,外部无法调用私有方法,且只有
#A类才能调用
示例:
class Shape:
def draw(self):
print('Shape.draw被调用')
class Point(Shape):
def draw(self):
print('正在画一个点')
class Circle(Point):
def draw(self):
print('正在画一个圆')
def my_draw(s): #不是C++/java必须要先指定s的类型
s.draw() #此处显示多态中的动态
s1 = Point()
s2 = Circle()
my_draw(s1)
my_draw(s2)
语法:
class 类名(基类名1,基类名2,........):
语句块
示例:
class Car:
def run(self,speed):
print('汽车正在以',speed,’的速度行驶')
def test(self): #演示名字冲突
print('Car.test被调用’)
class Plane:
def fly(self,height):
print('飞机正在海拔',height,'的高度飞行')
def test(self):
print('Plane.test被调用')
class CarPlane(Car,Plane): #飞车继承飞机和汽车类
pass
cp = CarPlane()
cp.fly(10000) #调用成功
cp.run(100) #调用成功
cp.test() #CarPlane中没有覆盖,父类名称冲突
#会调用继承列表(Car,Plane)中的第一个,这里是Car
#之后会类似广度优先的遍历(C3算法)-->python3
示例:
#此示例用来演示类的__mro__属性
class A:
def m(self):
print('A.m')
class B(A):
def m(self):
print('B.m')
super().m() #调用C.m不是A,因为继承调用是按mro顺序
class C(A):
def m(self):
print('C.m')
class D(B,C):
def m(self):
print('D.m')
super().m() #调用B.m
d = D()
print(D.__mro__) #D,B,C,A,object
总结:单继承中super一定调用继承列表内的父类
而多继承中的super不一定是父类,按照mro的广度优先列表\
练习:
#自定义Mylist类继承自list类并添加insert_head功能
class Mylist(list):
def insert_head(self,value):
self.insert(0,value) #可以直接使用父类的方法
L = Mylist(range(1,5)) #直接使用父类的初始化方法
print(L)
L.insert_head(0)
print(L)
L.append(5)
print(L)
repr(obj) 返回一个能代表此对象的表达式字符串,通常:
eval(repr(obj)) == obj
str(obj) 通过给定的对象返回一个字符串(这个字符串通常是
给人看的,没有字符两边的引号)
例如:
s = 'I am a Human'
s1 = repr(s) #eval(s1)返回s,能完全代表s的字面值
s2 = str(s)
print(s1) #'I am a Human' 是表达式
print(s2) #I am a Human
示例:
class MyNumber:
def __len__(self):
return 100
n1 = MyNumber()
x = len(n1) #重写了__len__方法才能这样调用
print('x = ',x)
repr()函数的重写方法:
def __repr__(self):
return 能够表达self内容的字符串
str()函数的重写方法:
def __str__(self):
return 人能看懂的字符串
说明:
(1)str(obj)函数优先调用obj.__str__()方法返回字符串
(2)如果obj没有__str__()方法,则调用obj.__repr__()方法返回
的字符串
(3)如果obj没有__repr__()方法,则调用object类的__repr__()实
例方法显示格式的字符串
(4)__str__ 在用户调用print打印对象时,该方法会自动执行。
(5)__repr__ 在机器(在python命令行中实例化对象后,再只写个对象名
回车)使用时自动执行。
注意:在没有写__str__方法的时候,且写了repr方法时。__str__=
__repr__
示例:
#此示例演示重写__repr__与__str__方法
class Student:
def __init__(self,name):
self.__name = name
def __str__(self):
return str(self.__name)
def __repr__(self):
return repr(self.__name)
s1 = Student('小王')
print(s1) #小王,优先调用__str__,
#若没有__str__而有__repr__则是'小王'
__abs__ __int__
__complex__ __float__
__reversed__ __bool__
__round__ __len__
格式:
def __bool__(self):
...
作用:
用于bool(obj)函数取值
用于if语句真值表达式中(若有__bool__方法,if obj会自动调用
并判断,否则__len__判断之后无条件为真)
用于while语句真值表达式中
说明:
1.优先调用__bool__()方法取值
2.如果不存在__bool__()方法,则调用__len__()方法去之后判断
是否为0值,不为0返回True,否则返回False
3.如果再没有__len__()方法,则直接返回True
示例:
#此示例示意bool函数的重写与len函数重写的关系
class Mylist:
def __init__(self,iterator = []):
self.data = [x for x in iterator]
#def __bool__(self):
# return bool(self.data)
#def __len__(self): #当没有bool重写时使用len重写
#的结果判断
# return len(self.data) #若同时没有len重写,则无条件
#返回True
l = Mylist([])
if l:
print('Ture')
else:
print('False')
语法形式:
class MyIterator:
def __next__(self):
迭代器协议的实现
return 数据
class MyIterable:
def __iter__(self):
语句块
return 迭代器 #必须返回迭代器
class Fibonacci:
def __init__(self,n):
'''此方法用于初始化Fib数列'''
self.__count = n
if n==1:
self.__it = [1]
elif n==2:
self.__it = [1,1]
elif n>2:
tmp = 2
self.__it = [1,1]
while tmp<=n:
self.__it.append(self.__it[tmp-1]+self.__it[tmp-2])
tmp+=1
def __iter__(self):
'''将Fib作为可迭代对象,必须返回迭代器'''
return MyIterator(self.__it) #此处也可以使用内建的迭代器
#如return iter(self.__it)
def __repr__(self):
'''向Fib数列提供打印功能'''
return '%r' % self.__it
class MyIterator:
'''自建迭代器(拥有__next__方法且方法返回值才算迭代器)'''
def __init__(self,iterable):
self.__cur = 0
self.__it = iterable
def __next__(self):
'''迭代器协议'''
if self.__cur >=len(self.__it):
raise StopIteration
self.__r = self.__it[self.__cur]
self.__cur+=1
return self.__r
def __str__(self):
'''向迭代器提供打印功能'''
return str(self.__r)
for x in Fibonacci(10):
print(x)
L = [x for x in Fibonacci(30)]
print(L)
print(sum(Fibonacci(25)))