面向对象:Object Oriented Programming,简称OOP,是一种程序设计思想,它将对象作为程序的基本单元 能指挥某某完成其能完成的功能
面向过程:核心是过程二字,过程指的是解决问题的步骤,即先干什么再干什么......面向过程的设计就好比精心设计好一条流水线,是一种机械式的思维方式。
面向对象和面向过程的优缺点
面向过程:
优点:复杂问题简单化(一步一步解决),流程化
缺点:机械化 扩展性差 如若修改 牵一发动全身
面向对象:
优点:提高了扩展性 复用性 可维护性提高
缺点:程序复杂程度变高了 无法预知完成的结果
适用场景:
面向过程:适合扩展性低的程序 著名的例子有Linux內核,git,以及Apache HTTP Server等
面向对象:适合扩展性高的程序 适合需求经常修改增加的程序
对象:属性和方法的结合体
类:一系列的相同属性和相同方法的集合体
注意: 在面向过程中 是先产生类 然后再去产生对象的
1.3 面向对象编程的思考过程
如果遇到面向对象的问题,首先想到的需要哪些对象,这些对象具备哪些属性和技能,再根据这些属性和技能去创建类,最后在创建对象出来
class Person: # 创建类 pass p1 = Person() # 创建对象
p1.name = 'tom'
print(p1.name) #输出 tom
为什么需要:
魔法方法 __xx__()的统称为魔法方法
案例:
class Student:
def __init__(self,name)
self.name = name
在创建对象时
小结
-
__init__ -
在创建对象时 会自动调用
__init__函数 -
自动传入对象本身进去
__new__
`__new__`方法的第一个参数是这个类,而其余的参数会在调用成功后全部传递给`__init__`方法初始化,这一下子就看出了谁是老子谁是小子的关系。 所以,`__new__`方法(第一个执行)先于`__init__`方法执行:
class A:
pass
class B(A):
def __init__(self):
print("__init__方法被执行")
def __new__(cls, *args, **kwargs):
print("__new__方法被执行")
return super().__new__(cls)
b = B()
'''
__new__方法被执行
__init__方法被执行
'''
小结
1.new的功能是在生成对象之前所做的动作,接受的参数是cls 类
2.init是在对象生成之后完善对象的属性 它接受的是self 对象
代码实现上面三句话
new的功能是在生成对象之前所做的动作.
class User:
def __new__(cls, *args, **kwargs):
print("new")
def __init__(self,name):
self.name=name
print("init")
print(type(User("body")))
结果:
new <class 'NoneType'> #
class User:
def __new__(cls, *args, **kwargs):
print("new")
return super().__new__(cls)
print(type(User("body")))
pass
new <class '__main__.User'>
我们调用了 父类的返回对象的方法return. 正如咱们所料 真的可以生成了对象.
__init__是在对象生成之后完善对象的属性
class User:
def __new__(cls, *args, **kwargs):
print("new")
return super().__new__(cls)
def __init__(self,name):
self.name=name
print("init")
print(type(User("body")))
pass
new init <class '__main__.User'>
总结
-
元类中的
__ call__()方法会在调用类时执行, -
可以用于控制对象的创建过程
__call__()
class A(object):
def __call__(self, x):
print('__call__ called, print x: ', x)
a = A()
a('123')
# __call__ called, print x: 123
class A(object):
def __init__(self, x):
print ('x in __init__', x)
def __new__(cls, y):
print ('y in __new__', y)
return super(A, cls).__new__(cls)
def __call__(self, z):
print( 'z in __call__', z)
A('123')('abc')
'''
y in __new__ 123
x in __init__ 123
z in __call__ abc
'''
class MyMeta(type):
# 获得某个类的实例
def __call__(self, *args, **kwargs):
print("call")
# return super().__call__(*args,**kwargs)
new_args = []
for i in args:
if isinstance(i,str):
# 如果是字符串的话就返回大写
new_args.append(i.upper())
else:
new_args.append(i)
return super().__call__(*new_args,**kwargs)
# 注意注意注意: __new__ __init__ 是创建类对象时还会执行
# __call__ 类对象要产生实例时执行
class Student(metaclass=MyMeta):
def __init__(self,name,gender,age):
self.name = name
self.gender = gender
self.age = age
s = Student("jack","woman",18)
print(s.name) # JACK
print(s.age) # 18
print(s.gender) # WOMAN
class Person(metaclass=MyMeta):
def __init__(self,name,gender):
self.name = name
self.gender = gender
p = Person("rose","man") #
print(p.name) # ROSE
'''
call
JACK
18
WOMAN
call
ROSE
'''
class Person:
def __init__(self,name,age):
self.name = name
self.age = age
# 将对象转换为字符串时执行
def __str__(self):
print("str run")
return "my name is %s , age is %s" % (self.name,self.age)
p = Person("rose",20)
print(p) #在打印前都会现将要打印的内容转为字符串 通过调用__str__函数
'''
str run
my name is rose , age is 20
'''
小结
-
__str__该方法在object中有定义 默认行为 返回对象类型以及地址 <main.Person object at 0x0000016F450C7390> -
在将对象转为字符串时执行,返回值是字符串
-
当使用print输出对象的时候,只要自己定义了
__str__(self)方法,那么就会打印从在这个方法中return的数据
"""
__del__
当对象被删除前会自动调用 该方法
声明时候会删除对象?
1.程序运行结束 解释器退出 将自动删除所有数据
2.手动调用del 时也会删除对象
注意:该函数不是用来删除对象的
使用场景
当你的对象在创建时,开启了不属于解释器的资源 例如打开了一个文件
必须保证当对象被删除时 同时关闭额外的资源 如文件
也称之为析构函数 构造 的反义词
构造 指的是从无到有
析构 值从有到无
简单的说就对象所有数据全部删除
总结:__del__该函数 用于 在对象删除前做一些清理操作
"""
# 假设要求每一个person对象都要绑定一个文件
class Person:
def __init__(self,name,path,mode="rt",encoding="utf-8"):
self.name = name
self.file = open(path,mode,encoding=encoding)
# 读取数据的方法
def read_data(self):
return self.file.read()
def __del__(self):
print("del run!")
self.file.close()
对象---子类>--->父类--->父类的父类.....object. object是所有的类的基类 子类有多个父类时,运用mro列表展示的顺序来查找
#A没有继承B,但是A内super会基于C.mro()继续往后找
class A:
def test(self):
super().test()
class B:
def test(self):
print('from B')
class C(A,B):
pass
c=C()
c.test() #打印结果:from B
print(C.mro())
#[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]