面向对象的学习,可让咱们的代码趋于模块化,规范化,尤为是引入设计模式以后,面向对象的优势就更加明显~~
但愿你们在实际使用中多使用面向对象的思想,enjoy!python
目前全部的文章思想格式都是:知识+情感。 知识:对于全部的知识点的描述。力求不含任何的自我感情色彩。 情感:用我本身的方式,解读知识点。力求通俗易懂,完美透析知识。
我给本篇文章的定位是回顾本身以前学过的知识点,必定会有我没有涉及到的知识点。我会将我本身学习面向对象以后使用过的,忘记了的,我以为本身须要掌握的内容,在正文中体现出来~~
花费了我很多时间,哈哈~~mysql
1.面向对象直接这么说,是很空的一个概念。尤为是初学者,你说面向对象,根本都不知道是什么,哪怕是学习了好久的人,你问什么是面向对象,十之八九的答案都是,面向对象就是写一个类。。。。terrible~, So, 先一步一步的来了解一下什么是面向对象吧~linux
2.看面向对象以前,想函数怎么能够执行,除了一个一个的向下执行,还能够嵌套使用吧!在函数中须要增长一个功能,我想须要更改的地方不一出,改完了,你敢肯定没有影响其余的功能吗???答案确定是,回去检查一下吧!咋们保险一点~sql
3.由此面向对象就引出来了,能够简单的理解为面相对象就是解决只使用函数的扩展性问题。(其实,这里有一个问题就是,我写过全是函数的代码,不知你是否写过,又真的有相同体会?)数据库
4.总结一下,面向对象解决了扩展性问题。由此,咋们一块儿上了面向对象的车,一路开向面向对象的本质~设计模式
接下来将开始,面向对象的第一次实质审查~~数组
一开始面向对象,你们会说Python里面一切皆对象,是否还记得linux里面一切皆文件~
补充一下,关于一切皆对象,对象怎么使用???
一、均可以被引用,x=obj
二、均可以看成函数的参数传入
三、均可以看成函数的返回值
四、均可以看成容器类的元素,例如: l=[func,time,obj,1]app
注意: Python3统一类与类型(数据类型)的概念,类型就是类。
上面这么说有一点空,看一个代码,但愿你们能够有所理解~(看到的数据类型都是类)框架
In [10]: print(list) <class 'list'> In [11]: print(str) <class 'str'> In [12]: print(dict) <class 'dict'>
1.现实生活中,须要先有了一个一个的对象,才能够将对象分为哪一类,哪一类,可是,在本身写程序的时候,须要本身先写到一个类,才能够产生一个的对象,产生对象的过程,称为实例化类。模块化
2.因此,必定是先有类,才能够实例化成为对象。
在建立类以前,须要掌握一点基础知识;
1.类中具备本身的数据,称为数据属性,或者叫数据
2.类中具备本身的函数,称为函数属性,或者叫方法
3.看下面建立的类,school属于数据,sleep属于方法
class Student: school = 'Peking University' def sleep(self): print('Student is sleeping.')
1.使用类,也就如何实例化出对象,根据上例子,student1=Student(),就能够实例化对象。
2.实例化类,并执行函数
In [16]: class Student: ...: school = 'Peking University' ...: ...: def sleep(self): ...: print('Student is sleeping.') ...: In [17]: student1 = Student() In [18]: student1.sleep() Student is sleeping.
注意:代码加载的时候,就会执行类,产生名称空间存储响应的数据,若是类中的数据属性有another操做,就会被执行。看下面的another操做是print操做。
In [15]: class Student: ...: school = 'Peking University' ...: print(school) ...: ...: def sleep(self): ...: print('Student is sleeping.') ...: Peking University
在这里将详细的讲一下,一个类中的属性与方法和实例化对象的关系!
1.类的属性是全部对象共同指向的,共同指向同一内存地址
验证:
In [20]: class Student: ...: school = 'Peking University' ...: ...: def sleep(self): ...: print('Student is sleeping.') ...: In [21]: student1 = Student() In [22]: student2 = Student() In [23]: id(student1.school) Out[23]: 1745287897136 In [24]: id(student2.school) Out[24]: 1745287897136
2.类的方法是绑定给每个对象的,对象调用的时候自动传参,bound method 。
验证:
In [29]: student1.sleep Out[29]: <bound method Student.sleep of <__main__.Student object at 0x000001965B6F95F8>> In [30]: student2.sleep Out[30]: <bound method Student.sleep of <__main__.Student object at 0x000001965B9F2CF8>>
1.类的命名空间查看,以下:
In [33]: Student.__dict__ Out[33]: mappingproxy({'__module__': '__main__', 'school': 'Peking University', 'sleep': <function __main__.Student.sleep(self)>, '__dict__': <attribute '__dict__' of 'Student' objects>, '__weakref__': <attribute '__weakref__' of 'Student' objects>, '__doc__': None})
2.能够执行下面的代码
类.__ dict __['name]
类.name
In [40]: Student.__dict__['school'] Out[40]: 'Peking University' In [41]: Student.school Out[41]: 'Peking University'
3.若是想要执行类中的函数属性,须要加上一个对象,来看下面,直接执行会报错,缺乏一个对象的参数。解决,传入一个对象便可。
In [42]: Student.sleep() --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-42-6e9af3d2ac0b> in <module> ----> 1 Student.sleep() TypeError: sleep() missing 1 required positional argument: 'self' In [43]: Student.sleep(student1) Student is sleeping.
1.init做为初始化,能够为每个对象定制属于本身的属性,只须要在实例化的时候传入便可。
2.方式一,实例化的时候,直接传参获得对象。
In [44]: class Student: ...: ...: school = 'Peking University' ...: ...: def __init__(self, name, age): ...: self.name = name ...: self.age = age ...: ...: def sleep(self): ...: print('%s is sleeping.' % self.name) ...: In [45]: student1 = Student('kate', 18) In [46]: student1.__dict__ Out[46]: {'name': 'kate', 'age': 18}
3.方式二,在使用方式一的时候,执行了两步,首先是实例化了对象,其次是传入参数,看下面,
In [48]: class Student: ...: ...: school = 'Peking University' ...: ...: def sleep(self): ...: print('Student is sleeping.') ...: In [49]: student2 = Student() In [50]: student2.name = 'kate' In [51]: student2.age = 18 In [52]: student2.__dict__ Out[52]: {'name': 'kate', 'age': 18}
bases的做用就是查看继承的父类有哪些,看下面例子,这个时候出现了一个object的类,可是咱们在书写类的时候,并无继承那个类啊,为何会多了一个object的类,有疑惑的请移步到新式类与经典类,默认Python3中都是继承object类的,不写也给你默认继承。
In [54]: Student.__bases__ Out[54]: (object,)
1.继承顾名思义就是继承,继承一个或者多个父类,被继承的类叫作基类(超类),继承者叫作子类(派生类)。其中,继承表示的是:什么是什么的关系。
2.继承以后,实例化的对象的属性查找,须要特别留意。对象的属性,在不继承的时候,先从本身属性查找,再从类中找,找不到就报错。若是有父类,会去父类中找,找不到报错。
3.总结: 继承的查找顺序----->先本身找,再去类中找,再去父类中找(父类中找也会出现问题,哪个先找呢,看mro表就知道了~~)
4.实际看一下继承的书写,(学生继承人这个类)
In [55]: class People: ...: ...: def __init__(self, name, age): ...: self.name = name ...: self.age = age ...: ...: def sleep(self): ...: print('%s is sleeping.' % self.name) ...: ...: ...: class Student(People): ...: ...: school = 'Peking University' ...: In [56]: student = Student('kate', 18) In [57]: student.__dict__ Out[57]: {'name': 'kate', 'age': 18}
1.在继承中,派生能够获得不一样于父类的属性与方法,有两种方式,下面咱们一块儿分别看一下~
2.指名道姓重用,(不依赖于继承)
In [65]: ...: class People: ...: ...: def __init__(self, name, age): ...: self.name = name ...: self.age = age ...: ...: def sleep(self): ...: print('%s is sleeping.' % self.name) ...: ...: ...: class Student(People): ...: school = 'Peking University' ...: ...: def sleep(self): ...: People.sleep(self) ...: print('Self sleeping....') ...: In [66]: stu = Student('kate', 18) In [67]: stu.sleep() kate is sleeping. Self sleeping....
3.使用super(),依赖于继承,使用mro表计算实现继承顺序,在mro也存在一个指针,只要是遇到super,就继续沿着mro表,继续向后找。
In [68]: class People: ...: ...: def __init__(self, name, age): ...: self.name = name ...: self.age = age ...: ...: def sleep(self): ...: print('%s is sleeping.' % self.name) ...: ...: ...: class Student(People): ...: school = 'Peking University' ...: ...: def sleep(self): ...: super(Student, self).sleep() ...: print('Self sleeping....') ...: In [69]: stu = Student('kate', 18) In [70]: stu.sleep() kate is sleeping. Self sleeping....
4,注意:通常的派生都是使用super()。而且更多的应用场景是在init中继承父类的内容,也有本身的内容。必定不要忘记子啊继承查找的时候,遇到super的试试,会继续向后查找的,就不会回到前面在查找了~~
mro列表,是查找继承的顺序列表,表示了属性的查找顺序。
例子:
In [71]: class A: ...: name = 'A' ...: ...: ...: class B(A): ...: name = "B" ...: ...: ...: class C(A): ...: name = "C" ...: ...: ...: class D(B, C): ...: name = 'D' ...: In [74]: D.mro() Out[74]: [__main__.D, __main__.B, __main__.C, __main__.A, object]
1.新式类,并非它有多么的新,哈~
新式类的讨论,须要分python2与Python3来讲了,接下来,没咱们一块儿来看看吧!
2.Python2的新式类,必须继承object类,继承object的类以及他的子类称为新式类。
3.Python3,默认全部 的类都是默认继承object类,因此都是新式类,也就是说Python3中没有经典类。
4.新式类在mro寻继承的时候,遵循广度优先。具体能够查看本身的mro列表。
1.经典类是专门来对于Python2来讲的,因此经典类说的是在Python2中, 没有继承object的类。
2.经典类在继承查询的时候,遵循的是深度优先。
1.组合,不须要深刻的了解,当一个类不能经过继承实现关系的时候,有须要本身有本身有什么关系的时候,就可使用派生。此时就,派生出本身的属性与方法。
In [58]: class People: ...: ...: def __init__(self, name, age): ...: self.name = name ...: self.age = age ...: ...: def sleep(self): ...: print('%s is sleeping.' % self.name) ...: ...: ...: class Student(People): ...: ...: school = 'Peking University' ...: ...: ...: class Course: ...: ...: def __init__(self, name, price): ...: self.name = name ...: self.price = price ...: In [59]: student = Student('kate', 18) In [60]: math = Course('math', 666) In [61]: student.course = math In [62]: student.__dict__ Out[62]: {'name': 'kate', 'age': 18, 'course': <__main__.Course at 0x1965b5c1198>} In [63]: student.course.name Out[63]: 'math' In [64]: student.course.price Out[64]: 666
2.此时表示给对象绑定了一个对象做为他的属性,能够实现代码的重用。
Python属于多态的语言,多态更多的体如今方法的调用上,保证多个类能够实现调用同一种方法,实现相同的任务。
回想,len(),这个内置函数,在执行的时候,能够对字符串,对列表,对元祖获取数据的长度,可是不一样的数据类型都是不同的类,可是实现了一样的函数方法。感受本身解释不清楚了,看代码吧!
In [1]: a = 'hello' In [2]: b = (1, 2, 3) In [3]: c = [4, 5, 6] In [4]: len(a) Out[4]: 5 In [5]: len(b) Out[5]: 3 In [6]: len(c) Out[6]: 3 In [8]: a.__len__ Out[8]: <method-wrapper '__len__' of str object at 0x000002B0701D12D0> In [9]: b.__len__ Out[9]: <method-wrapper '__len__' of tuple object at 0x000002B070404EE8> In [10]: c.__len__ Out[10]: <method-wrapper '__len__' of list object at 0x000002B0703C0588>
鸭子类型,具体的概念我就不解释了!我想解释的是,鸭子模式体现的是多态性,正如上文我所述的len()内置方法。它属于一个比较理论的知识内容,Python语言自己就具体多态性,因此本身在学习的时候,按需进行学习!
1.封装做为面向对象的特性之一,就我目前的理解,封装主要是对数据的隐藏,或者是变成本身私有的,因为Python语言的特性,会在内部自动对杠杠开头的变量进行相应的处理,因此正好使用这一特性实现数据隐藏。
2.具体的实现,隐藏,使前面加 __,此时的 __name 变为 **_类名__name,在类的加载阶段已经变化了,加上前缀的类名。**
3.看下命名空间,应该能够理解的吧~
In [11]: class People: ...: ...: def __init__(self, name, age): ...: self.__name = name ...: self.__age = age ...: ...: def sleep(self): ...: print('%s is sleeping.' % self.__name) ...: In [12]: human = People('kate', 18) In [13]: human.__dict__ Out[13]: {'_People__name': 'kate', '_People__age': 18}
4.封装能够将封装起来的数据,本身进行定义,不须要调用者操做与查看,不只仅是封装数据,还隔离复杂度。
在面向对象高阶,咱们开始一步一步的去寻找类的产生源头~~追根溯源。
1.抽象类的实现,使用的是abc模块,子哎程序的设计模式中可能会使用到,我在设计模式的文章中写过~,主要使用的是Python的abc模块
2.抽象类的特性:** 只能被继承,不能被实例化。只要是继承抽象类的类,必须重写相应的类方法,名字都必须同样,否则报错~,这在设计模式的时候,就很好的规范了底层的调用接口。**
3.例子,实现抽象类
In [17]: import abc ...: ...: ...: class People(metaclass=abc.ABCMeta): ...: ...: @abc.abstractmethod ...: def sleep(self): ...: pass ...: ...: ...: class Student(People): ...: school = 'Peking University' ...: ...: def __init__(self, name, age): ...: self.name = name ...: self.age = age ...: ...: def sleep(self): ...: print('Self sleeping....') ...: In [18]: stu = Student('kate', 18) In [19]: stu.__dict__ Out[19]: {'name': 'kate', 'age': 18}
1.property 将访问函数属性变为访问数据属性的方法。本来须要加上括号才能够调用,如今直接就能够进行调用了。统一调用形式,不用加括号进行调。用了
2.能够联动设置的参数,修改:name.setter, 删除:name.deleter
3.代码实现,了解一下,这个property仍是很经常使用的,
In [23]: class People: ...: ...: def __init__(self, name): ...: self.__name = name ...: ...: @property ...: def name(self): ...: return self.__name ...: ...: @name.setter ...: def name(self, new_name): ...: self.__name = new_name ...: ...: ...: @name.deleter ...: def name(self): ...: print('Error .... no permission to delete..') ...: IIn [24]: human = People('kat') In [26]: human.name Out[26]: 'kat' In [27]: human.name = 'kate' In [28]: human.name Out[28]: 'kate' In [29]: del human.name Error .... no permission to delete..
classmethod属于绑定到类的方法,类可使用,而且将类做为第一个参数传递进去。此时,能够回忆一下开始面向对象的时候,关于数据属性是全部的对象共同拥有的,全部的函数属性是绑定给每个对象。注意:bond method
看如下关于classmethod的例子:
In [30]: class People: ...: ...: def __init__(self, name): ...: self.__name = name ...: ...: @classmethod ...: def eat(self): ...: print('eat....') ...: ...: def sleep(self): ...: print('sleep...') ...: In [31]: peo = People('kate') In [32]: peo.sleep Out[32]: <bound method People.sleep of <__main__.People object at 0x000002B071C3E898>> In [33]: peo.eat Out[33]: <bound method People.eat of <class '__main__.People'>> In [34]: People.sleep Out[34]: <function __main__.People.sleep(self)> In [35]: People.eat Out[35]: <bound method People.eat of <class '__main__.People'>>
staticmethod表示非绑定方法,对象和类均可以使用,通常没有什么具体的意思,就是一个普通的函数,我在使用的过程当中也没有遇到,使用方法相似于classmethod。能够百度了解一下~~
反射,这个使用的次数是不少的,尤为是在不少开源的框架(Django 的框架中配置文件中的应用类,内部都是使用getattr)中都使用,这个方法很巧妙,能够字符串与函数关联起来。便可以经过字符串映射到对象的属性。
hasatrr单独使用是没有啥用的,只是作一个判断,看下对象中是否是存在一个字符串对应的属性。
grtattr 是真正干活的那个,能够进行字符串与函数属性的映射,操做起来至关顺溜~~,必定要多使用,尤为是在开放封闭原则的配置文件,配置参数的时候局可使用。
setattr通常使用的不多,我在上次学习到如今基本上没有怎么使用。
基本不使用的命令了,没使用过,要是不看到他了,我都忘记了这个了......
In [39]: class Ftp: ...: ...: def start(self): ...: while 1: ...: inp = input('>>>').strip() ...: cmds = inp.split() ...: if hasattr(self, cmds[0]): ...: func = getattr(self, cmds[0]) ...: func(cmds) ...: ...: def put(self, cmds): ...: print(cmds) ...: ...: def get(self, cmds): ...: print(cmds) ...: In [40]: f =Ftp() In [41]: f.start() >>>get d.md ['get', 'd.md'] >>>put s.doc ['put', 's.doc']
item系列,主要是将取出类中的数据属性,变成字典的方式取出,相应的包含getitem, setitem, delitem,实现属性的增删改查。
In [1]: class Student: ...: def __init__(self, name): ...: self.name = name ...: ...: def __getitem__(self, item): ...: print('getitem...') ...: return self.__dict__.get(item) ...: ...: def __setitem__(self, key, value): ...: print('setitem.... %s' % value) ...: self.__dict__[key] = value ...: ...: def __delitem__(self, key): ...: print('delitem....') ...: del self.__dict__[key] ...: In [2]: stu = Student('kate') In [3]: stu.name Out[3]: 'kate' In [4]: stu['name'] getitem... Out[4]: 'kate' In [5]: stu['age'] getitem... In [6]: stu['age'] = 18 setitem.... 18 In [7]: stu['age'] getitem... Out[7]: 18 In [8]: del stu['age'] delitem.... In [9]: stu.__dict__ Out[9]: {'name': 'kate'}
类中定义__str__以后,会在打印print的时候,自动触发对应的方法,得到该方法的返回值进行输出,因此str方法必须有返回值,且必须是字符串类型。目前在数据库表中使用过,So,须要学会使用~
In [10]: class Student: ...: ...: def __init__(self, name): ...: self.name = name ...: ...: def __str__(self): ...: print('__str__ method') ...: return self.name ...: In [11]: stu = Student('kate') In [12]: print(stu) __str__ method kate
iter方法比较经常使用,在python中实现了__iter__方法的对象是可迭代的。实际上要想让一个迭代器工做,至少要实现__iter__方法和next方法。
In [20]: class Test(): ...: def __init__(self,data): ...: self.data = data ...: ...: def __iter__(self): ...: return self ...: def __next__(self): ...: if self.data > 5: ...: raise StopIteration ...: else: ...: self.data+=1 ...: return self.data ...: In [21]: t = Test(3) In [22]: t Out[22]: <__main__.Test at 0x1d9198679e8> In [23]: for i in t: ...: print(i) ...: 4 5 6
1.了解del以前,但愿你们能够回一下本身在文件操做的时候,是否是须要打开文件以后必需要关闭文件啊!不想本身的关闭的时候,能够指定使用with语句进行关闭,可是这里就出现了一个问题,程序运行结束打开的文件是否是关闭了??
2.已经引出del的做用了,del是实现回收操做系统资源,打开文件是操做系统打开文件,并非本身的英语程序打开,想一下软件是运行在操做系统上的,操做系统创建在硬件的基础之上,得到f文件句柄是是应用程序的变量,记住,文件句柄f是应用程序的一个变量,指向的是操做系统的打开文件的资源,调用read函数的时候,是去操做系统的内存取数据,完了,晕了晕了,可自行百度一下~~
3.就算del不实现,在程序结束的时候,程序也会自动的时间回收系统资源。在这里瞬间让我想到了numpy中建立一个空数组的时候,会出现非0的空数组,里面包含的资源就是遗留的内存数据~~
doc方法是建立类的时候,书写注释以后就能够自动触发该方法执行,而且在这里面能够看到对应的注释内容。
调用对象的时候,在实例化的对象的后面加上括号,自动触发call执行。还记的怎么触发init方法执行不,是否是实例化对象的时候触发执行~
In [24]: class School: ...: ...: def __init__(self): ...: print('init....') ...: ...: def __call__(self, *args, **kwargs): ...: print('call....') ...: ...: In [25]: s = School() init.... In [26]: s() call....
1.单例模式,须要好好地掌握,在程序的设计模式中存在,在实际的使用中会使用,我推荐两种实现单例模式的方法。
2.第一种实现单例模式,在类模块中直接实例化成为一个对象,在其余模块引入调用的时候,直接调用已经实例化的对象便可,此时就实现了调用的单例模式。
3.在类的内部进行是否已经有实例化的判断,若是已经实例化,就须要将以前的实例化对象返回便可。
4.单例模式的优势,将参数相同的属性在内存中指向同一个地方,优化的策略。
5.简单实现单例模式,类内部判断方法
In [34]: class Mysql: ...: __instance = None ...: ...: def __init__(self): ...: self.host = '127.0.0.1' ...: self.port = 3306 ...: ...: @classmethod ...: def singleton(cls): ...: if not cls.__instance: ...: mysql = cls() ...: cls.__instance = mysql ...: return cls.__instance ...: In [35]: m = Mysql.singleton() In [36]: n = Mysql.singleton() In [37]: m Out[37]: <__main__.Mysql at 0x1d919a8fda0> In [38]: n Out[38]: <__main__.Mysql at 0x1d919a8fda0>
终于来到面向对象的高阶中的顶级了~~~让咱们一块儿,看看类的祖宗~
1.须要了解的东西,元类,顾名思义就是说产生类的类都是元类,其实就是type~
2.此时咱们就能够获得定义类的两种方式: 使用class 或者 使用元类
3.使用元类定义类的三要素:** 类名 继承类 命名空间
类名: 固然是本身起什么就是什么了
继承类: 没有多继承,那 object 仍是须要继承的
命名空间: 这个就须要本身结合以前学过一个内置函数 exec() ** ,这个函数的执行会产生相应的局部命名空间与全局命名空间。
4.尝试使用元类定义一个类~,看下面的例子:
注意: 使用exec的时候,若是不将exec内部书写的字符串数据定格书写会报错的,语法不能解析~~~
In [41]: # 定义类的三要素:类名,类的基类们,类的名称空间 ...: class_name = 'Chinese' ...: class_bases = (object,) ...: ...: class_body = """ ...: country='China' ...: ...: def __init__(self, name): ...: self.name=name ...: ...: def area(self): ...: print('%s is area' % self.name) ...: """ ...: ...: class_dic = {} ...: exec(class_body, globals(), class_dic) # Execute the given source in the context o ...: f globals and locals. ...: ...: Chinese = type(class_name, class_bases, class_dic) # 元类type定义类,type(name, ba ...: ses, dict) -> a new type ...: In [42]: obj1 = Chinese('kate') In [43]: obj1.name Out[43]: 'kate' In [44]: obj1 Out[44]: <__main__.Chinese at 0x1d919881be0>
使用元类控制类的行为,包括控制类的建立行为,与实例化行为。
1.控制建立行为能够实现, 建立的类必须首字母大写, 必须写注释。。。。,而且能够直接在Mymeta类中添加属性,子类直接能够进行调用。
In [49]: class Mymeta(type): ...: def __init__(self, class_name, class_bases, class_dic): ...: self.country = 'china' ...: ...: if '__doc__' not in class_dic or not class_dic.get('__doc__').strip(): ...: raise TypeError('必须为类指定文档注释') ...: ...: if not class_name.istitle(): ...: raise TypeError('类名首字母必须大写') ...: ...: super(Mymeta, self).__init__(class_name, class_bases, class_dic) ...: ...: ...: class Student(object, metaclass=Mymeta): ...: """ ...: Student class ...: """ ...: def __init__(self, name, age): ...: self.name = name ...: self.age = age ...: ...: ...: stu = Student('kate', 18) ...: In [50]: stu.__dict__ Out[50]: {'name': 'kate', 'age': 18}
2.控制类的实例化行为, 使用的是 触发__call__方法,这个时候就本身建立一个空对象,并调用init函数,返回对象,实现自动触发init执行的内容。
In [49]: class Mymeta(type): ...: def __init__(self, class_name, class_bases, class_dic): ...: self.country = 'china' ...: ...: if '__doc__' not in class_dic or not class_dic.get('__doc__').strip(): ...: ...: if not class_name.istitle(): ...: raise TypeError('类名首字母必须大写') ...: ...: super(Mymeta, self).__init__(class_name, class_bases, class_dic) ...: ...: def __call__(self, *args, **kwargs): ...: obj = object.__new__(self) # 实例化Student,产生空对象obj ...: self.__init__(obj, *args, **kwargs) # 调用Student下的函数__init__,初始化o ...: bj ...: return obj # 返回初始化好了的obj ...: ...: ...: class Student(object, metaclass=Mymeta): ...: """ ...: Student class ...: """ ...: ...: def __init__(self, name, age): ...: self.name = name ...: self.age = age ...: ...: ...: stu = Student('kate', 18) In [52]: stu.__dict__ Out[52]: {'name': 'kate', 'age': 18}
结束了面向对象的内容,长出一口气,又陷入了新的迷茫~
面向对象的内容,远不止我所述的这些,还有不少,尤为是面向对象的思想,Python的一切皆对象,底层的不少杠杠方法,我我的以为,学习重在思考与实践与总结。
但愿你们阅读愉快~