面向对象
- 面向对象基础
'''
类:
是对某种物种的一种抽象表达。
比如人类,人类是我们对人的一种抽象,他有年龄属性,身高属性,奔跑,吃饭等行为。
对象:
对象是对类的一种具体化。
比如具体的某个人,他是属于人类这个类的,但他是个确确实实存在的实体。总结就是,对象是类的一种具体实现。
'''
class Person(object):
'''
类:
定义一个类的语法是使用class关键字,开发者自己定义的类,必须继承自object类,
object类是Python中所有的类的基类。类中所有的方法都要以self作为第一个参数传递进去,
这是规定。self代表的是当前的对象。
'''
def __init__(self,name,age):
self.name = name
self.age = age
def eat(self):
print('我是%s,我吃饭比较文静'%self.name)
class Car(object):
def __init__(self,brand,xinghao):
self.brand = brand
self.xinghao = xinghao
def run(self):
print('我是%s车,型号是%s,我现在在跑'%(self.brand,self.xinghao))
'''
对象:对象是对类的一个实例化,对象的创建方式如下(比如要实现一个Person的对象)
'''
p1 = Person('1','2')
p1.eat()
c1 = Car('1','2')
c1.run()
- 构造函数和实例属性
#1.定义类必须使用class关键字,然后继承自object类
#2.在类中定义方法,第一个参数必须是self,self代表的是当前这个对象
class Person(object):
def __init__(self,name,age):
self.name = name
#def ------(self,aaa,bbb):
# self.name = aaa
self.age = age
print('*'*30)
print(id(self))
print('*' * 30)
def eat(self):
print('我在吃饭')
#3.使用类创建一个对象:类名()
p1 = Person('zhiliao','18')
print(p1.name)
print(p1.age)
#调用方法
p1.eat()
print('='*30)
print(id(p1))
print('='*30)
p2 = Person('zhiliao111','18111')
print(p2.name)
print(p2.age)
- 访问限制
# 1.受保护的属性或者方法
'''
受保护的属性和方法:
有时候在类中的属性或者是方法不想被外界调用,但还是可以被外界所调用,
那么就叫做受保护的属性或者方法。受保护的属性或者方法,使用一个下划线开头
'''
class Women(object):
def __init__(self,age):
#定义一个受保护的age属性
self._age = age
women = Women(19)
print(women._age)
# 2.私有属性或者方法
'''
私有属性和方法:
有时候在类中的属性或者方向不让外界调用,那么就可以使用定义成私有属性或者私有方法。
私有属性或者方法使用两个下划线开头
'''
class Account(object):
def __init__(self,a_id,password):
self.a_id = a_id
self.__password = password
def __account_list(self):
print('我是一个私有方法')
return [11,-11,33]
def get_account_list(self,password):
if password==self.__password:
return self.__account_list()
else:
return None
account1 = Account('xxxxx','123456')
print(account1.a_id)
# print(account1.__password)
# account1.__account_list()
print(account1._Account__password)
account1.get_account_list('123456')
- 实例组装电脑
#CPU/RAM/Dist
class CPU(object):
"""
cpu类
"""
def __init__(self,brand,core,interface):
self.brand = brand
self.core = core
self.interface = interface
class RAM(object):
"""
ram类
"""
def __init__(self,brand,size):
self.brand = brand
self.size = size
class Disk(object):
def __init__(self,brand,size):
self.brand = brand
self.size = size
class Computer(object):
"""
电脑类
"""
def __init__(self,cpu_interface,ram_count,dis_count):
self.cpu_interface = cpu_interface
self.ram_count = ram_count
self.dis_count = dis_count
self.__cpu = None
self.__rams = []
self.__disks = []
def add_cpu(self,cpu):
if cpu.interface == self.cpu_interface:
self.__cpu = cpu
else:
print('cpu型号不对,不能安装')
def add_ram(self,ram):
if len(self.__rams) == self.ram_count:
print('内存条已经没有位置安装了')
else:
self.__rams.append(ram)
def add_disk(self,disk):
if len(self.__disks) == self.dis_count:
print('硬盘已经没有位置')
else:
self.__disks.append(disk)
def run(self):
if not self.__cpu:
print('没有cpu,电脑不能正常运行')
return
elif len(self.__rams) == 0 or len(self.__rams) > self.ram_count:
print('内存条安装失败,电脑不能正常运行')
return
elif len(self.__disks) == 0 or len(self.__disks) > self.dis_count:
print('硬盘安装失败')
return
else:
print('所有配件都安装完毕,电脑正常启动...')
def main():
#初始化一台电脑
computer = Computer('11211',2,2)
#初始化一个cpu
cpu = CPU('intel',4,'11211')
#创建两个内存条
ram1 = RAM('jinshidun','4G')
ram2 = RAM('jinshidun','4G')
#创建两个硬盘
disk1 = Disk('jinshidun','256G')
disk2 = Disk('jinshidun','256G')
#组装cpu
computer.add_cpu(cpu)
#组装内存条
computer.add_ram(ram1)
computer.add_ram(ram2)
#组装硬盘
computer.add_disk(disk1)
computer.add_disk(disk2)
#让电脑跑起来
computer.run()
if __name__ == '__main__':
main()
- 析构函数与引用计数
import sys
class Person(object):
def __init__(self):
self.name = 'zhiliao'
print('这是构造函数')
self.fp = open('xx.txt','w')
def greet(self):
print('hello,woshi%s'%self.name)
def write(self,message):
self.fp.write(message)
'''
Python中的类也有析构函数,也即__del__方法,只要这个对象在内存中即将被消灭的时候,就会调用这个方法
'''
def __del__(self):
print('这是析构函数')
self.fp.close()
P = Person()
P.greet()
'''
引用计数:Python中的对象是使用引用计数的方式实现的。也即如果没有任何对象引用到一块内存,那么Python将会把这块内存回收
'''
print(sys.getrefcount(P))
P.write('xxx')
p2 = P
print(sys.getrefcount(P))
- 继承
#封装/继承/多态
#继承
#父类/基类
class Person(object):
def __init__(self,name,age):
self.name = name
self.age = age
def eat(self):
print('人在吃饭')
def run(self):
print('人在跑步')
'''
继承可以使用其他类当作自己的父类,那么父类中的方法和公有属性都可以被子类使用。继承的好处是可以让子类节省代码,实现更多的功能
'''
class Student(Person):
pass
s = Student('zhilaio','12')
print(s.age)
s.eat()
- 重写父类方法
class Person(object):
def __init__(self,name,age):
self.name = name
self.age = age
def eat(self):
print('人在吃饭')
class Student(Person):
#1.如果父类的方法不能满足子类的需求,那么可以重写这个方法,以后对象调用同名
#方法的时候,就只会之星子类这个方法
#2.虽然父类的方法不能完全满足子类的需求,但是父类的方法的代码还是需要执行,
#那么可以通过super这个函数来调用父类的方法。
#3.用法:super(类名,self).方法名([参数])
def __init__(self,name,age,sex):
super(Student,self).__init__(name,age)
self.sex = sex
def greet(self):
print('hello my name is %s,my age is %d,i am %s'%(self.name,self.age,self.sex))
def eat(self):
super(Student,self).eat()
print('学生在吃饭')
s = Student('zhiliao',12,'男')
s.greet()
s.eat()
- 父类中的私有属性或方法不能被子类继承
#父类的私有属性或者私有方法,子类不能用
class Person(object):
def __init__(self,name):
self.__name = name
self._age = 12
def greet1(self):
print('hello,my name is %s' % self.__name)
class Student(Person):
def greet2(self):
print('hello,my age is %d' % self._age)
s1 = Student('zhiliao')
s1.greet2()
- 旧式类
#旧式类:没有指定任何父类。
#在Python2.2版本之前,所有的类都是旧式类
class Person:
def __init__(self,name):
self.name = name
#在旧式类中,子类能使用super函数调用父类的函数
class Student(Person):
def __init__(self,name):
print('这是student类的代码')
super(Student,self).__init__(name)
s1 = Student('zhiliao')
print(s1.name)
# #明确的指定了继承的父类。
# class Person(object):
# def __init__(self,name):
# self.name = name
- 多态与多继承
class Hero(object):
def __init__(self):
pass
def stroke(self):
pass
class Chengyaojin(Hero):
def stroke(self):
print('程咬金的回血大招')
class Xiangyu(Hero):
def stroke(self):
print('项羽的推人大招')
value = input('请选择英雄')
hero = None
if value == '1':
hero = Chengyaojin()
else:
hero = Xiangyu()
hero.stroke()
class Animal(object):
def eat(self):
print('动物吃东西')
class Ma(Animal):
def qima(self):
print('骑马')
def eat(self):
print('马吃草')
super(Ma,self).eat()
print('马吃完了草')
class Lv(Animal):
def lamo(self):
print('驴拉磨')
def eat(self):
print('驴吃麦子皮')
super(Lv,self).eat()
print('驴吃完了麦子皮')
class Luozi(Ma,Lv):
def eat(self):
super(Luozi,self).eat()
print('骡子既吃草又吃麦子皮')
luozi = Luozi()
luozi.eat()
print(Luozi.__mro__)
'''
在新式类中,如果多继承,那么将采用C3算法,使用的是广度优先的算法,打印Class.__mro__可以看到基类执行的顺序。 在旧式类中,如果多继承,那么将采用深度优先的算法。
'''
- 类属性和实例属性
class Person(object):
country = 'china'
def __init__(self,name,country):
self.country = country
self.name = name
def greet(self):
#如果对象上没有country属性,那么通过self.country 和 Person.country的效果是一样的
#如果给对象绑定的country属性,那么通过self.country访问到的就是这个对象上的属性,通过Person.country访问到的就是类属性
print('My name is %s,i am come from %s'%(self.name,Person.country))
# #实例属性:绑定到对象上的属性就是实例属性
# p1 = Person('zhiliao')
# p1.age = 18
#
#
# #实例属性只在当前对象上有作用
# p2 = Person('zhiliao')
# # print(p2.age)
# print(p2.name)
#类属性:
#如何在类中定义类属性
#类属性可以通过对象进行访问
#如果通过对象修改类属性,那么其实不是修改类属性,而是在这个对象上面重新定义了一个名字相同的实例属性
p1 = Person('zhiliao')
p1.country = 'earth'
print(p1.country)
print(Person.country)
p2 = Person('ketang')
p2.country = 'usa'
print(p2.country)
print(Person.country)
#要正确的修改类属性只能通过类名的方式进行修改
Person.country = 'abc'
print(Person.country)
- 静态方法和类方法
class Person(object):
country = 'china'
def eat(self):
print('hello world')
#类方法:第一个参数必须是cls,cls代表当前这个类,可以去修改类属性
@classmethod
def greet(cls):
cls.country = 'zhiliao'
print('zhiliao ketang')
#静态方法不需要传递对象或者类,认为是一个普通的函数
#使用场景:不需要修改类或者对象的属性时,并且这个方法放在类中可以让代码更具有管理性
@staticmethod
def static_methon():
print('hello')
Person.country = 'qqq'
#实例方法
p1 = Person()
# p1.eat()
# Person.eat()
#类方法
# 1.使用类名
# Person.greet()
# 2.使用对象
# p1.greet()
# print(Person.country)
# # Person.greet()
# p1.greet()
# print(Person.country)
# 静态方法,和类方法调用方式一样
Person.static_methon()
p1.static_methon()
- __new__函数
#__new__方法
#创建对象(__new__) => 初始化对象(__init__)
#单例:定义好的类只能有一个对象
class Car(object):
def __new__(cls, *args, **kwargs):
print('new method')
#return None
#切记,必须要在new方法后面返回当前这个类的对象
return super(Car,cls).__new__(cls,*args,**kwargs)
def __init__(self):
print('car init method')
car = Car()
print(car)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class Person(object):
# __new__方法的参数不是self,而是cls,代表当前这个类
def __new__(cls,*args,**kwargs):
print('new方法执行')
# 一定要返回对象,不然就不会创建对象
# object的__new__不接收参数,因此__new__方法不能传入*args和**kwargs参数
return super(Person,cls).__new__(cls)
# __init__方法是在对象被创建完毕后进行一些初始化的
# 因此这时候是self,因为这个对象已经存在了
def __init__(self):
print('init方法执行')
# __del__方法是在这个对象被销毁的时候调用的
def __del__(self):
print('del方法执行')
p = Person()
# 打印顺序
# 1. new方法执行
# 2. init方法执行
# 3. del方法执行
- 创建单例对象
#单利设计模式:某个类或者模型在整个程序运行期间最多只能有一个对象被创建
#我们可以判断,如果User这个类没有创建过对象,那么可以创建一个对象保存在某个地方
#以后如果要在创建对象,我会去判断,如果之前已经创建了一个对象,那么就不在创建
#而是直接把之前那个对象返回回去
'''
单例的意思是:
在程序中,某个类的对象只有一个。
这种需求其实很常见,比如一个项目中有一个配置文件,那么可以通过定义一个Config的类来操作配置信息,
但是配置信息在整个项目中其实只需要一份就够了,这时候就可以使用到单例模式了
'''
class User(object):
__instance = None
def __new__(cls, *args, **kwargs):
if not cls.__instance:
cls.__instance = super(User,cls).__new__(cls)
return cls.__instance
def __init__(self,name):
self.name = name
def share_user(cls):
return User()
user = User.share_user()
# user1 = User('zhiliao')
# user2 = User('ketang')
#
# print(id(user1))
# print(id(user2))
#
# print(user1.name)
# print(user2.name)