面向对象: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'>]