第一章 两大编程思想
1.编程思想
两者是相辅相成的,不是对立的。
2.类和对象
字符串对象,字典对象…都可以看作是对象。
3.类的创建
下面介绍如何在python中定义类
语法:
class 类名
缩进之后开始写类地下的内容
类应该有三部分组成:id (内存空间),type(类型),值
class Student():
pass
print(id(Student)) 类的内存空间
print(type(Student)) 类的类型
print(Student) 类的值
那么类当中都有哪些部分组成呢?
分为 类属性,实例方法,静态方法,类方法
class Student():
native_place = '山东' #直接写在类里的变量称为类属性
def __init__(self,name,age): #初始化方法
self.name = name #赋值操作,后面是局部变量,把局部变量赋给前面的实例属性
self.age = age
# 实例方法 类之外定义的称为函数,类之内称为方法
def eat(self):
print('吃饭') #和函数定义方法类似,但是它多了一个self
@staticmethod
def method():
print('我使用了staticmethod,所以我是静态方法')
#静态方法中的括号不加任何参数,静态方法主要是用来存放逻辑性的代码,
#主要是一些逻辑属于类,但是和类本身没有实际性的交互,但是需要让这个功能成为这个类的成员,
#那么就可以采用静态方法。在静态方法中,不会涉及到类中的方法和属性的操作
@classmethod
def method(cls):
print('我是类方法,因为我使用了classmethod进行修饰')
#类方法里面要传参数cls
4.对象的创建
对象的创建,也就是类里面的对象如何实例化,如何使用
接着上面的代码
#创建Student的对象 stu1
stu1 = Student('张三',24)
print(id(stu1))
print(type(stu1))
print(stu1)
如图所示,创建的stu1是实例对象,而Student是类对象
有了实例对象就可以调用类对象的方法了,还可以输出类的属性,也就是实例的属性
#创建Student的对象 stu1
stu1 = Student('张三',24)
stu1.eat()
print(stu1.name)
print(stu1.age)
或者调用方法的时候这样操作也可以,之前我们说定义eat方法的时候有个参数self,这里stu1就相当于把self补上了
#创建Student的对象 stu1
stu1 = Student('张三',24)
stu1.eat()
Student.eat(stu1)
5.类属性 类方法 静态属性的使用方法
类属性:
#类属性的使用方法
# print(Student.native_place)
stu1 = Student('张三',24)
stu2 = Student('李四',34)
print(stu2.native_place)
print(stu1.native_place)
Student.native_place = '北京' 改变了原来定义的出生地
print(stu2.native_place)
print(stu1.native_place)
类方法和静态方法:
#类方法的使用方式,直接用调用类方法名即可
Student.cs()
#静态方法的使用方式
Student.method()
6.动态绑定属性和方法
我们先创建Student的两个实例对象stu1和stu2
class Student():
def __init__(self,name,age):
self.name = name
self.age = age
def eat(self):
print(self.name + '在吃饭')
stu1 = Student('张三',23)
stu2 = Student('李四',24)
print(id(stu1))
print(id(stu2))
然后呢我们想为stu1创建一个属性,性别属性,让他可以输出性别,同时呢我们还不想让stu2输出这个属性,只想让stu1有这个属性,那就用到我们的动态绑定
#为stu1动态绑定性别属性
stu1.gender = '女'
print(stu1.name,stu1.age,stu1.gender)
print(stu2.name,stu2.age,stu2.gender)
我们可以看到stu.gender会报错
除了可以绑定属性,还可以动态的绑定方法
#动态绑定方法
def show():
print('定义在类之外的,称为函数')
stu1.show=show()
stu1.show
而如果stu2调用的时候就会出现报错,因为这是为stu1专门绑定的方法
实例方法的调用:
这两种调用方法都可以,直接用对象.可以,也可以传入对象来
第二章 面向对象的三大特征 封装继承多态介绍
这是第二章的主要内容
1. 封装
#这里的class Car里面的内容就是封装
class Car():
def __init__(self,brand):
self.brand = brand
def start(self):
print('汽车已经启动')
car = Car('奥迪')
print(car.brand)
对于我们不希望在类对象外部访问的定义方式:
class Student():
def __init__(self,name,age):
self.name = name
self.__age = age #不希望年龄在类的外部被使用,加两个__
def show(self):
print(self.name,self.__age)
stu = Student('张三',20)
stu.show()
#在类的外面使用name和age
print(stu.name)
print(stu.__age)
在类的外面使用age会报错
但是实际上可以使用age来访问,下面介绍方法
print(dir(stu))
print(stu._Student__age)
这样就可以访问了。
2.继承
如图所示,鳄鱼和蛇是属于爬行动物,所以爬行动物是鳄鱼和蛇的父类,同理哺乳动物是老虎猴子等的父类,动物是爬行动物和哺乳动物的父类,而动物是老虎猴子鳄鱼蛇等动物的祖先类
class Person(object): #Person继承Object类,括号内不写也是代表默认继承Object
def __init__(self,name,age):
self.name = name
self.age = age
def info(self):
print(self.name,self.age)
#定义Person的子类
class Student(Person):
def __init__(self,name,age,stu_no):
super().__init__(name,age)
self.stu_no = stu_no
class Teacher(Person):
def __init__(self,name,age,teacheryear):
super().__init__(name,age)
self.teacheryear= teacheryear
stu = Student('张三',23,202133)
teacher = Teacher('李四',34,8)
stu.info() #这俩的info都是从父类person中继承来的
teacher.info()
多继承
class A(): ()里面可以写object也可以不写,不写就默认继承object
pass
class B():
pass
class C(A,B):
pass
3.方法重写
如果父类的方法没有我们想要的,就可以进行方法的重写。比如上面一节person类的那个例子,继承父类的info方法我们只能输出年龄和姓名,我们还想要输出学生的学号以及老师的教龄,这样父类的方法满足不了我们,就只能进行对父类方法的重写。
class Person(object): #Person继承Object类,括号内不写也是代表默认继承Object
def __init__(self,name,age):
self.name = name
self.age = age
def info(self):
print(self.name,self.age)
#定义Person的子类
class Student(Person):
def __init__(self,name,age,stu_no):
super().__init__(name,age)
self.stu_no = stu_no
def info(self):
super().info() #继承父类的方法就是输出姓名年龄
print(self.stu_no) #这样只能输出学号,要还想要输出姓名啥的要上面一行
class Teacher(Person):
def __init__(self,name,age,teacheryear):
super().__init__(name,age)
self.teacheryear= teacheryear
def info(self):
super().info()
print('教龄',self.teacheryear)
stu = Student('张三',23,202133)
teacher = Teacher('李四',34,8)
stu.info() #这俩的info都是从父类person中继承来的
print('----------------')
teacher.info()
4。object类
class Student():
def __init__(self,name,age):
self.name = name
self.age = age
#object类有个str的方法,用于返回对象的描述,
stu = Student('张三',25)
print(dir(stu))
print(str(stu))
在这里我们看到我们没有给student定义方法,但是它有很多方法,原因就是它继承的object,也就是object的方法。str实际输出的是对象的内存地址
class Student():
def __init__(self,name,age):
self.name = name
self.age = age
#object类有个str的方法,用于返回对象的描述,
#我们可以重写str方法,让他去输出对象的属性值
def __str__(self):
return '我的名字是{0},今年{1}岁了'.format(self.name,self.age)
stu = Student('张三',25)
print(stu) #这时候就不输出stu的内存地址了
经常在写完这个类之后重新写str方法,用于返回对象的描述
5.多态的实现
class Animal():
def eat(self):
print('动物吃')
class Dog(Animal):
def eat(self):
print('狗吃肉')
class Cat(Animal):
def eat(self):
print('猫吃鱼')
class Person():
def eat(self):
print('人吃好吃的')
def fun(obj): #定义一个函数
obj.eat()
#开始调用我们的函数
fun(Cat()) #为什么加()是因为这个cat等也是个实例化的过程
fun(Dog()) #只是没有将其赋值如果只要cat这是一个类名,它没有实例化
fun(Animal()) #这里的cat和dog都是继承的animal
print('------------')
fun(Person()) #person和前面不存在继承关系,但是它有eat方法,所以它会调用person中的eat方法
你不用关心person是谁的子类,你只要关系person 中有没有eat方法即可
java就是静态语言,而python是动态语言
6.特殊属性
class A():
pass
class B():
pass
class C(A,B):
def __init__(self,name,age):
self.name = name
self.age = age
x = C('LAME',24) #c类的实例化
print(x.__dict__) #获得实例对象的属性字典
print(C.__dict__) #类对象的属性和方法的字典
print('------------------')
print(x.__class__)#会输出类所属的类型
print(C.__bases__)#输出C类的父类都有哪些
print(C.__base__)#输出离着最近的父类
print(C.__mro__)#输出类的层次结构
print(A.__subclasses__()) #输出A的子类
- 特殊方法
a = 1
b = 2
c = a+b
d = a.__add__(b) #上面那个加法的操作实际上就是调用add进行相加
print(c)
print(d)
class Student():
def __init__(self,name):
self.name = name
stu1 = Student('张三')
stu2 = Student('李四')
s = stu1+stu2 #我们这样是没有办法相加的,因为都是Student类型
print(s)
但是我们可以用特殊方法来改写
class Student():
def __init__(self,name):
self.name = name
def __add__(self, other):
return self.name+other.name #这样就实现了两个对象的加法运算,编写了add特殊的方法
stu1 = Student('张三')
stu2 = Student('李四')
s = stu1+stu2 #我们这样是没有办法相加的,因为都是Student类型
ss= stu1.__add__(stu2)
print(s)
print(ss)
class Student():
def __init__(self,name):
self.name = name
def __add__(self, other):
return self.name+other.name #这样就实现了两个对象的加法运算,编写了add特殊的方法
def __len__(self): #我们之前len(stu1)的时候肯定报错,重写之后就不会了
return len(self.name)
stu1 = Student('lalala')
stu2 = Student('李四')
s = stu1+stu2 #我们这样是没有办法相加的,因为都是Student类型
ss= stu1.__add__(stu2)
print(s)
print(ss)
L= [11,12,13]
l = len(L)
print(L.__len__())
print(l)
print(len(stu1))
lalala是6个字符
- __new__方法和__init__方法
这两个方法是创建对象用的