1 面向对象
面向过程是先分析出解决问题的步骤,再把步骤拆成一个个方法,是没有对象去调用的,通过一个个方法的执行解决问题。(需要实现一个功能的时候,重要的是过程,分析出一个个步骤,并把一个个步骤用一个个函数去实现,再依次去调用一个个函数即可,每一个步骤都需要自己亲力亲为)
面向对象是将编程当成一个事物(对象),对外界来说,事物是直接使用的,不用去管内部的情况,而编程就是设置事物能做什么事情。(需要实现一个功能的时候,看重的是谁去帮我做这件事情
2 类和对象
类是对一系列具有相同属性和行为的事物的统称,是一个抽象的概念,不是真实存在的事物。类的三要素:类名(人类);类属性(身高、体重、年龄),对象的特征描述,用来说明是什么样子的;实例方法(走路、说话、学习),对象具有的功能,用来说明能够做什么。
#类的基本格式
#class 类名(遵循大驼峰命名法):
# 代码块
class Washer:
height=800 #类属性,就是类所拥有的属性
#查看类属性:类名.属性名
print(Washer.height) #800
#新增类属性:类名.属性名=值
Washer.width=450
print(Washer.width) #450
对象是类的具体表现,是面向对象编程的核心,在开发中先有类再有对象。创建对象的过程也叫实例化对象
#类的基本格式
#class 类名(遵循大驼峰命名法):
# 代码块
class Washer:
height=800 #类属性,就是类所拥有的属性
#实例化对象的基本格式:对象名=类名()
#实例化一个洗衣机对象
wa=Washer()
print(wa) #<__main__.Washer object at 0x0000020B9B9A0FD0> 对象的内存地址
#第二次实例化
wa2=Washer()
print(wa2) #<__main__.Washer object at 0x0000020196950FA0> 可以实例化多个对象
实例方法
实例方法由对象调用,至少有一个self参数,执行实例方法的时候,自动将调用该方法的对象赋值给self
class Washer:
height=800 #类属性,就是类所拥有的属性
def wash(self): #实例方法
print("我会洗衣服")
print("方法中的self:",self)
#实例化对象
wa=Washer()
print(wa)
#对象调用类中方法
wa.wash()
"""
<__main__.Washer object at 0x0000023A70C91FD0>
我会洗衣服
方法中的self: <__main__.Washer object at 0x0000023A70C91FD0>
"""
#实例化对象2
wa2=Washer()
print(wa2)
wa2.wash()
"""
<__main__.Washer object at 0x0000023A70C91F10>
我会洗衣服
方法中的self: <__main__.Washer object at 0x0000023A70C91F10>
"""
实例属性
类属性和实例属性的区别:类属性属于类,是公共的,大家都能访问到,实例属性是属于对象的,是私有的,只能由对象名访问,不能由类名访问
#实例属性格式:self.属性名
class Person:
name="bingbing" #类属性
def introduce(self): #实例方法
print("我是实例方法")
print(f"{Person.name}的年龄:{self.age}") #self.age是实例属性,这里Person.name也可以改为self.name
pe=Person()
pe.age=18
pe.introduce()
"""
我是实例方法
bingbing的年龄:18
"""
3 构造函数
构造函数__init__(),通常用来做属性初始化或者赋值操作,在类实例化对象的时候,会被自动调用
class Test:
def __init__(self): #有self,说明是实例方法
print("这是__init__()函数")
te=Test()
#这是__init__()函数
太固定了
class Person:
def __init__(self): #有self,说明是实例方法
self.name="bingbing" #实例属性
self.age=18
self.height=160
def play(self):
print(f'{self.name}在玩游戏')
def introduce(self):
print(f'{self.name}的年龄是{self.age},身高是{self.height}')
pe=Person()
pe.play()
pe.introduce()
pe2=Person()
pe2.play()
pe2.introduce()
"""
bingbing在玩游戏
bingbing的年龄是18,身高是160
bingbing在玩游戏
bingbing的年龄是18,身高是160
"""
class Person:
def __init__(self,name,age,height):
self.name=name
self.age=age
self.height=height
def play(self):
print(f'{self.name}在玩游戏')
def introduce(self):
print(f'{self.name}的年龄是{self.age},身高是{self.height}')
pe=Person("bingbing",18,160)
pe.play()
pe.introduce()
pe2=Person("hh",20,163)
pe2.play()
pe2.introduce()
"""
bingbing在玩游戏
bingbing的年龄是18,身高是160
hh在玩游戏
hh的年龄是20,身高是163
"""
4 __new__()
__new__()是object基类提供的内置的静态方法,主要作用是在内存中为对象分配空间,并返回对象的引用,python解释器在获取到对象的引用后,将引用作为第一个参数传递到init方法,因此init中的self就代表对象本身。new方法是object里面的默认方法,前面提及的__init__并不是第一个被调用的方法,第一个被调用的是__new__(),不会打印出这是__init__()是因为new会将init覆盖
class Test(object):
def __init__(self):
print("这是__init__()")
def __new__(cls, *args, **kwargs): #cla代表类本身
print("我是__new__()")
te=Test()
"""
我是__new__()
"""
第二种方式print(te)不会出现内存地址,而是显示None,这是因为new方法相当于重写了,覆盖了父类的new方法
class Test(object):
def __init__(self):
print("这是__init__()")
te=Test()
print(te)
"""
这是__init__()
<__main__.Test object at 0x000001D300D60FD0>
"""
class Test(object):
def __init__(self):
print("这是__init__()")
def __new__(cls, *args, **kwargs):
print("这是__new__()")
print(cls)
te=Test()
print(te)
"""
这是__new__()
<class '__main__.Test'>
None
"""
重写__new__()一定要return super().__new__(cls),否则python解释器得不到分配空间的对象引用,就不会调用__init__()。
class Test(object):
def __init__(self):
print("这是__init__()")
def __new__(cls, *args, **kwargs):
print("这是__new__()")
print(cls)
#对父类方法进行扩展
res=super().__new__(cls) #方法重写,res里面保存的是实例对象的引用
return res
te=Test()
print(te)
"""
这是__new__()
<class '__main__.Test'>
这是__init__()
<__main__.Test object at 0x00000124B9A51F10>
"""
综上,一个对象的实例化过程:首先执行__new__()(如果没有重写new方法,那么就默认调用object基类提供的__new__()方法)返回一个实例对象,然后将实例对象作为第一个参数self传递给__init__()方法中,然后对对象进行初始化。
new和init的区别:new是创建对象,init是初始化对象;new是返回对象引用,init是定义实例属性;new是类级别的方法,init是实例级别的方法
class Person(object):
def __new__(cls, *args, **kwargs):
print("这是__new__()")
print(super().__new__(cls))
return super().__new__(cls)
def __init__(self,name):
self.name=name
print("名字是:",self.name)
pe=Person('bingbing')
print(pe)
"""
这是__new__()
<__main__.Person object at 0x0000018118B81E50>
名字是: bingbing
<__main__.Person object at 0x0000018118B81E50>
"""
5 析构函数
析构方法__del__是对象在被垃圾回收的时候起作用的一个方法,它的执行一般也就意味着对象不能继续引用,回收内存。
正常运行时不会调用__del__(),执行结束之后,系统会自动调用__del__()。
class Person:
def __init__(self):
print("我是__init__()")
def __del__(self):
print("被销毁了")
p=Person()
print("这是最后一行代码")
"""
我是__init__()
这是最后一行代码
被销毁了
"""
del p语句执行的时候,内存会立即被回收,会调用对象本身的__del__()方法
class Person:
def __init__(self):
print("我是__init__()")
def __del__(self):
print("被销毁了")
p=Person()
del p
print("这是最后一行代码")
"""
我是__init__()
被销毁了
这是最后一行代码
"""