一、面向对象之多态

  1、多态:简而言子就是多种形态或多种类型

  python中不支持多态也用不到多态,多态的概念是应用与java/C#中指定传参的数据类型,

  java多态传参:必须是传参数的数据类型或传参的子类类型

  面向对象总结:

  面向对象是一种编程方式,此编程方式的实现是基于对象的使用

  类:是一个模板,模板中包含了多个函数共使用,即类中可包含多个函数(类中的函数即叫做方法)

一般疑问:

  1)什么样的代码才是面向对象?

  简单来说,如果程序中的所有功能否是由 “类”和“对象”实现,那么就是面向对象编程

  2)函数式编程和面向对象如果选择?分别在什么情况下使用?

  C#和java只支持面向对象编程,不支持函数式编程

  python和PHP则支持两种编程方式,且函数式编程能完成的操作,面向对象都可以实现;而对象能实现的操作,函数则不行(函数式编程无法实现面向对象的封装功能)

  python编程中,全部使用面向对象或面向对象和函数式混合使用

  1、多个函数使用共同的值:类中的函数俗称为一个方法

  1. #!/usr/bin/env python
  2. # -*- coding:utf-8 -*-
  3. # Author:lcj
  4. #Blog address(博客地址):http://i.cnblogs.com/EditPosts.aspx?postid=5500010&update=1
  5. #学号:stu179501 password:055bc2457dfa2e
  6.  
  7. class hh:
  8. def __init__(self,host,user,pwd):
  9. self.host = host
  10. self.user = user
  11. self.pwd = pwd
  12. #增加
  13. def zengjia(self,sql):
  14. print(self.host)
  15. print(self.user)
  16. print(self.pwd)
  17. print(sql)
  18. #删除
  19. def shangchu(self,sql):
  20. print(sql)
  21. #修改
  22. def xiugai(self):
  23. print(self.host)
  24. print(self.user)
  25. print(self.pwd)
  26. #查
  27. def cha(self):
  28. pass
  29. #将动态传输'localhost','lcj',123传给__init__方法中host,user,pwd
  30. obj1 = hh('localhost','lcj',123)
  31. # obj1.zengjia('selet * from A') #有对象调用方法时系统会自动执行__init方法并将动态参数selet * from A传递个sql
  32. ##输出
  33. #localhost
  34. # lcj
  35. # 123
  36. # selet * from A
  37. # obj2 = hh('localhost','lcj',123)
  38. # obj2.shangchu('select * from lcj')
  39. # #修改,host,用户名,密码
  40. obj3 = hh('127.0.0.1','xiaoluo',123)
  41. obj3.xiugai()
  42. # 127.0.0.1
  43. # xiaoluo
  44. # 123

  2、需要创建多个事务,每一个事务属性个数相同,但是值得需求如:姓名、年龄、血型都不相同,即属性个数相同,但是值不相同

  1. class dome():
  2. def __init__(self,name,age,xuexing):
  3. self.name = name
  4. self.age = age
  5. self.xuexing = xuexing
  6. def tail(self):
  7. temp = "My nian%s age%s 血型%s"%(self.name,self.age,self.xuexing) #指定站位符记性传参
  8. print(temp)
  9. obj1 = dome('lcj',12,'O')
  10. obj1.tail()
  11. # My nianlcj age12 血型O
  12. obj2 = dome('xiaoluo',18,'O')
  13. obj2.tail()
  14. # My nianxiaoluo age18 血型O

二、面向对象中类成员

  python类成员包含:字段、方法、属性

  1、字段

  普通字段:保存在对象中 ,存在于对象中,一般情况下由对象访问普通字段

  静态字段:属于类中,保存在内里面,即在类下面,由“类”访问静态字段

  注意:一般情况下,自己访问自己,静态字段中(在万不得已情况下可以用对象访问静态字段)

  静态字段在代码加载时已经创建,而对象则需要创建并调用才能将数据存放在内存

  由图可知:

  • 静态字段在内存中只保存一份
  • 普通字段在每一个对象中都要保存

  应用场景:通过类创建对象时,如果每一个对象中都包含相同的字段,那么就可使用静态字段(静态字段存在于类面)

  1. class Province:
  2. #静态字段
  3. Country = '世界'
  4. def __init__(self,name):
  5. #普通字段
  6. self.name = name
  7. #一般情况下,自己访问自己
  8. zh = Province('中国')
  9. print(zh.name) #对象访问普通字段
  10. #静态字段:只有类才能访问,在万不得已下可以用对象访问静态字段
  11. print(zh.Country)
  12. #由类访问静态字段
  13. print(Province.Country)

  2、方法

  python中什么是方法?

  定义:将函数放至类中,且传参中含有“slef”,表示方法

  方法:静态方法、普通方法及类方法三种方法在内存中都归属类,其他语言中只含有两种方法:静态方法和普通普通方法

  1)静态方法:

  静态方法:调用静态方法时,需再方法前加@staticmethod,参数即可有可无,一般由类执行静态方法(不到万不得已时,可用对象调用静态方法),静态方法中参数可有可无

  1. class Province:
  2. #静态字段
  3. Country = '世界'
  4. def __init__(self,name):
  5. #普通字段
  6. self.name = name
  7. #普通方法,与对象调用(方法属于类)
  8. def show(self):
  9. print(self.name)
  10. #静态方法:两步,去掉self,二,添加装饰器@staticmethod
  11. @staticmethod
  12. def f1(arg1,arg2):
  13. #静态方法由类调用,(当方法内部不需要对象中封装的值时,可以将方法写成静态方法)
  14. print(arg1,arg2)
  15. # obj1 = Province(456,234)
  16. # obj1.f1() #由对象调用静态方法,则报错
  17. #类调用静态方法
  18. Province.f1(111,122)
  19. # 111 122

  2)普通方法

  创建普通方法时参数中必须带一个self关键字,当任意对象执行普通方法时,自动将调用该方法的对象赋值给self

  3)类方法:

  创建规则:创建类方法规则:普通方法前加@classmethod ,参数中必须带一个“cls”关键字,执行类方法时,自动将调用该方法的类赋值给cls关键字

  特点:由类调用类方法时,系统自动将当前类名传递给cls参数

  1. class Province:
  2. #静态字段
  3. Country = '世界'
  4. def __init__(self,name):
  5. #普通字段
  6. self.name = name
  7. #普通方法,与对象调用(方法属于类)
  8. def show(self):
  9. print(self.name)
  10. #静态方法:两步,去掉self,二,添加装饰器@staticmethod
  11. @staticmethod
  12. def f1(arg1,arg2):
  13. #静态方法由类调用,
  14. print(arg1,arg2)
  15. #类方法:由类调用,
  16. @classmethod
  17. # 类方法参数中至少有“cls"参数
  18. def f2(cls): #调用类方法时,系统自动将当前类名传递给cls
  19. print(cls)
  20. #类调用静态方法
  21. Province.f1(111,122)
  22. # 111 122
  23. Province.f2()
  24. #<class '__main__.Province'>

  3、属性

  定义:不伦不类的东西

  规则:在创建属性时,在普通方法基础上添加@property装饰器,属性仅有一个self参数,调用时无需加括号,方法:foo_obj.func(),属属性:foo_obj.prop

按照对象调用方法进行访问形式且执行调用方法时不加“括号”,ret = obj.show 【obj属于对象,show属于对象中存在的方法】

  特点:具有方法的写作形式(),又有字段的访问形式(字段是用过对象访问,且访问时不加“括号”进行访问)

  Python的构造方法中有四个参数:

  1. 第一个参数是方法名,调用 对象.属性 时自动触发执行方法
  2. 第二个参数是方法名,调用 对象.属性 XXX 时自动触发执行方法
  3. 第三个参数是方法名,调用 del 对象.属性 时自动触发执行方法
  4. 第四个参数是字符串,调用 对象.属性.__doc__ ,此参数是该属性的描述信息
  1. class Foo:
  2.  
  3. def get_bar(self):
  4. return 'lcj'
  5.  
  6. # *必须两个参数
  7. def set_bar(self, value):
  8. return 'set value' + value
  9.  
  10. def del_bar(self):
  11. return 'qaz'
  12.  
  13. BAR = property(get_bar, set_bar, del_bar, 'description...')
  14.  
  15. obj = Foo()
  16.  
  17. ret = obj.BAR # 自动调用第一个参数中定义的方法:get_bar
  18. print(ret)
  19. ret= obj.BAR = "xiaoluo" # 自动调用第二个参数中定义的方法:set_bar方法,并将“alex”当作参数传入
  20. print(ret)
  21. del Foo.BAR # 自动调用第三个参数中定义的方法:del_bar方法
  22. # obj.BAE.__doc__ # 自动获取第四个参数中设置的值:description...

  通过方法完成分页:

  1. #通过方法计算分页
  2. class www:
  3. def __init__(self,all_count):
  4. self.all_count = all_count
  5. def show(self):
  6. #divmod:计算分页,a1表示商,a2:表示余数
  7. a1,a2 = divmod(self.all_count,10)
  8. if a2 == 0:
  9. return a1
  10. else:
  11. return a1 + 1
  12. obj = www(101) #创建obj1对象,并把101参数赋值给对象obj
  13. ret = obj.show() #由对象调用show方法,并将返回结果值赋值给一个变量
  14. print(ret)
  15. # 11

  通过添加属性@property,再由对象调用方法执行

  1. class www:
  2. def __init__(self,all_count):
  3. #字段all_count
  4. self.all_count = all_count
  5. #属性
  6. @property
  7. def show(self):
  8. #divmod:计算分页,a1表示商,a2:表示余数
  9. a1,a2 = divmod(self.all_count,10)
  10. if a2 == 0:
  11. return a1
  12. else:
  13. return a1 + 1
  14. obj = www(101) #创建obj1对象,并把101参数赋值给对象obj
  15. # ret = obj.all_count #对象调用字段all_count
  16. # print(ret) 101
  17. # ret = obj.show() #由对象调用show方法,并将返回结果值赋值给一个变量
  18. # print(ret)
  19. # 11
  20. ret3 = obj.show #通过对象调用方法,此时方法已经被属性化,无需加()即可执行show方法
  21. print(ret3)
  22. # 11

  对属性中的数值进行“修改(添加装饰器@show.setter)、删除(添加装饰器@show.deleter)”操作,show属于方法

  1. class www:
  2. def __init__(self,all_count):
  3. #字段all_count
  4. self.all_count = all_count
  5. #属性
  6. @property
  7. def show(self):
  8. #divmod:计算分页,a1表示商,a2:表示余数
  9. a1,a2 = divmod(self.all_count,10)
  10. if a2 == 0:
  11. return a1
  12. else:
  13. return a1 + 1
  14. #修改属性中的数值
  15. @show.setter
  16. def show(self,value):
  17. print(value)
  18. #对属性中数值进行删除
  19. @show.deleter
  20. def show(self):
  21. print('del show')
  22. obj = www(101) #创建obj1对象,并把101参数赋值给对象obj
  23. # ret = obj.all_count #对象调用字段all_count
  24. # print(ret) 101
  25. # ret = obj.show() #由对象调用show方法,并将返回结果值赋值给一个变量
  26. # print(ret)
  27. # 11
  28. # print(obj.all_count)
  29. # obj.all_count = 102 #对字段进行重新赋值
  30. # print(obj.all_count)
  31. # del obj.all_count #删除字段中的数字
  32. ret = obj.show
  33. print(ret)
  34. #修改属性中的数值
  35. obj.show = 123
  36. #删除属性中值
  37. del obj.show

  方式二:foo = property(F1,F2,F3)

  1. class lcj:
  2. def __init__(self,count):
  3. self.count = count
  4. pass
  5. def F1(self):
  6. return 111
  7. def F2(self,value):
  8. pass
  9. def F3(self):
  10. print('hahaha')
  11. #当对象调用foo方法时,系统会自动执行指定的方法
  12. foo = property(F1,F2,F3)
  13. obj = lcj(124)
  14. #打印原属性中的值
  15. ret = obj.foo
  16. print(ret) # 返回值:111
  17. #修改属性值
  18. ret = obj.foo = 1000
  19. print(ret) #返回修改属性值为:1000
  20. del obj.foo #返回删除属性中的值:hahaha

三、类成员的修饰符

  类成员修饰符可分:公共成功和私有成员

  1、什么是公共成员和私有成员?

  公共成员:在任何地方都能访问,即可在类外面和对象调用方法进行访问

  私有成员:只有在类的内部才能访问

  1. class C:
  2.  
  3. def __init__(self):
  4. self.name = '公有字段'
  5. self.__foo = "私有字段"

  创建私有成员规则:即在字段前面添加两个双下划线:__字段,且只能有内部访问(通过对象调用私有字段访问),外部访问不了

  2、私有成员:私有成员命名时,前两个字符时下划线,特殊成员除外:如:(__init__、__call__、__dict__等)

  即私有字段:只能类自己本身成员内部可以访问,其他成员访问不了

  静态字段:公有静态字段和私有静态字段

  公有静态字段:类可以访问,类内部可以访问;派生类中也可访问  

  1. class foo:
  2. name = '公共静态字段'
  3. def __init__(self,name):
  4. self.name = name #公有静态字段
  5. def f1(self):
  6. print(self.name)
  7. class fol(foo):
  8. def f2(self):
  9. print(self.name)
  10. #类访问公共静态字段
  11. print(foo.name) #公共静态字段
  12. #类内部通过对象访问方法
  13. obj = foo('lcj')
  14. obj.f1() #lcj
  15. #中派生类中可以访问
  16. obj2 = fol('xiaoluo')
  17. obj2.f2() #先去fol类中执行f2方法,如没有则在父类foo中执行f2方法
  18. #xiaoluo

  私有静态字段:仅类内部可以访问

  1. class foo:
  2. #创建私有静态字段
  3. __age = 18
  4. def __init__(self,name):
  5. #创建私有字段:__name
  6. self.__name = name
  7. def f1(self):
  8. print(self.__name)
  9. #创建静态方法
  10. @staticmethod
  11. def f2():
  12. print(foo.__age)
  13. foo.f2() #通过类直接调用静态方法中F2方法

    3、公有成员:

  【不到万不得已不要在外部强制访问私有成员】  

  1. class foo:
  2. #创建私有静态字段
  3. __age = 18
  4. def __init__(self,name):
  5. #创建私有字段:__name
  6. self.__name = name
  7. def f1(self):
  8. print(self.__name)
  9. # 强制访问私有字段,对象+一个下划线+类名+两个下划线+参数
  10. obj = foo('xiaoluo')
  11. print(obj._foo__name)
  12. # xiaoluo

四、类的特殊成员

   常用类成员有:__doc__,__module__和__class__, __init____del____call__ __dict__,, __str____getitem__、__setitem__、__delitem__,__getslice__、__setslice__、__delslice__,__iter__ __new__ 和 __metaclass__

  1、__doc__:表示类的描述

  1. class foo:
    #构造方法
    def __init__(self,name):
    self.name= name
    #输出描述信息
    obj= foo('lcj')
    print(obj.name) #调用对象时,系统自动执行__init__方法,输出:lcj
    print(foo.__doc__)#None

  2、__module__和__class__  

  __module__ 表示当前操作的对象在那个模块

  __class__     表示当前操作的对象的类是什么  

  1. class lcj:
  2. def __init__(self):
  3. self.name ='xiaoluo'
  1. from lib.s4 import lcj #导入模块
  2. obj =lcj() #创建对象
  3. print(obj.__module__) #输出lib.s4模块
  4. print(obj.__class__) # 输出类<class 'lib.s4.lcj'>

  练习:

  1. class ww:
  2. #创建构造方法
  3. def __init__(self,name,age):
  4. self.name = name
  5. self.age = age
  6. #析构方法:当对象结束对方法调用时,系统自动执行析构方法
  7. def __del__(self):
  8. pass
  9. #call方法:
  10. def __call__(self, *args, **kwargs):
  11. print("call")
  12. #将对象转化至字符串类型,并按照字符串进行输出
  13. def __str__(self):
  14. return ("%s ---%d"%(self.name,self.age))
  15. #执行call方法:对象+()
  16. obj1 = ww('lcj',18)
  17. # obj1() #call
  18. ww()()
  19. # obj2 = ww('lcc',18)
  20. # print(obj1)
  21. # print(obj2)

  3、 __init__

  构造方法:通过类创建对象时,系统触发执行__init__方法

  1. class lcj:
  2. #创建构造方法
  3. def __init__(self,name,gender,age,):
  4. self.name = name
  5. self.gender = gender
  6. self.age = age
  7. def f1(self):
  8. print("i am is %s,性别:%s,年龄:%s"%(self.name,self.gender,self.age))
  9. #创建对象obj,self=obj,并将参数传递给__init__方法
  10. obj = lcj("xiaoluo",18,"男")
  11. obj.f1()
  12. # i am is xiaoluo,性别:18,年龄:男

  4、__del__

  析构方法,当对象在内存中释放时,系统自动触发执行(释放内存空间,充当垃圾回收)

注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。  

  1. class lcj:
  2. #创建构造方法
  3. def __init__(self,name,gender,age,):
  4. self.name = name
  5. self.gender = gender
  6. self.age = age
  7. def f1(self):
  8. print("i am is %s,性别:%s,年龄:%s"%(self.name,self.gender,self.age))
  9. #析构方法,
  10. def __del__(self):
  11. pass
  12. #创建对象obj,self=obj,并将参数传递给__init__方法
  13. obj = lcj("xiaoluo",18,"男")
  14. obj.f1()
  15. # i am is xiaoluo,性别:18,年龄:男

  5、__call__

  调用方式:对象+(),即触发执行__call__方法

  注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()  

  1. class lcj:
  2. #创建构造方法
  3. def __init__(self,name,gender,age,):
  4. self.name = name
  5. self.gender = gender
  6. self.age = age
  7. def f1(self):
  8. print("i am is %s,性别:%s,年龄:%s"%(self.name,self.gender,self.age))
  9. #析构方法,
  10. def __del__(self):
  11. pass
  12. #创建__call__方法
  13. def __call__(self, *args, **kwargs):
  14. print(self.name,self.gender,self.age)
  15. #创建对象obj,self=obj,并将参数传递给__init__方法
  16. obj = lcj("xiaoluo",18,"男")
  17. # obj.f1() #执行__init__方法
  18. obj() #对象+():执行__call__方法
  19. # xiaoluo 18 男

  6、__dict__

  获取类和对象中所有成员

  类的普通字段属于对象,类的静态字段和方法等属于类

  1. class lcj:
  2. #创建静态字段
  3. think = "思考中的人"
  4. #创建构造方法
  5. def __init__(self,name,age):
  6. self.name = name
  7. self.age = age
  8. def f1(self,*args,**kwargs):
  9. pass
  10. #获取类中成员,即:静态字段、方法
  11. print(lcj.__dict__)
  12. #输出:{'f1': <function lcj.f1 at 0x000000000110CEA0>, '__module__': '__main__', '__init__': <function lcj.__init__ at 0x000000000110CE18>, '__dict__': <attribute '__dict__' of 'lcj' objects>, '__weakref__': <attribute '__weakref__' of 'lcj' objects>, 'think': '思考中的人', '__doc__': None}
  13. #创建对象
  14. obj = lcj("xiaoluo",18)
  15. #获取对象中的各成员
  16. print(obj.__dict__)
  17. #输出:{'name': 'xiaoluo', 'age': 18}

  __add__(self, other)方法:

  1. class lcj:
  2. def __init__(self,name,age):
  3. self.name = name
  4. self.age = age
  5. def f1(self):
  6. print("i am is %s age%s"%(self.name,self.age))
  7. #__add__方法
  8. def __add__(self, other):
  9. tem = "%s ---%d"%(self.name,other.age)
  10. return tem
  11. obj1 = lcj("xiaoluo",19)
  12. obj2 = lcj("haha",18)
  13. ret = obj1 + obj2 #两对象相加
  14. print(ret)
  15. #输出:xiaoluo ---18

   7、__str__

  如果一个类中定义了__str__方法,那在打印“对象”时,默认输出该方法的返回值

  1. class xiaoluo:
  2. #调用对象时,默认输出__str_方法返回值
  3. def __str__(self):
  4. return ("haha")
  5. obj = xiaoluo()
  6. print(obj)
  7. #输出:haha

  8、__getitem__、__setitem__、__delitem__

  用于索引操作又可做切片方式操作,如字典,以上分别获取,设置,删除数据

  1. class lcj:
  2. #构造方法
  3. def __init__(self,like,yanse):
  4. self.like = like
  5. self.yanse = yanse
  6. #获取
  7. def __getitem__(self, key):
  8. print(self.__getitem__,key)
  9. #修改key和value
  10. def __setitem__(self, key, value):
  11. print(self.__setattr__,key,value)
  12. #删除key
  13. def __delitem__(self, key):
  14. print(self.__delitem__,key)
  15. obj = lcj("蓝天","蓝色的天空")
  16. obj['xiaoluo'] #系统自动触发__getitem__方法
  17. #输出:<bound method lcj.__getitem__ of <__main__.lcj object at 0x0000000000B4A8D0>> xiaoluo
  18. obj['k2'] = '中国梦'
  19. #输出:<method-wrapper '__setattr__' of lcj object at 0x0000000001132438> k2 中国梦
  20. del obj['lcj'] #自动触发:__delitem__方法
  21. #输出:<bound method lcj.__delitem__ of <__main__.lcj object at 0x00000000011724A8>> lcj

  切片方式:

  1. class lcj:
  2. #构造方法
  3. def __init__(self,like,yanse):
  4. self.like = like
  5. self.yanse = yanse
  6. #获取
  7. def __getitem__(self, key):
  8. print(self.__getitem__,key)
  9. print(key.start)
  10. print(key.stop)
  11. print(key.step)
  12. #修改key和value
  13. def __setitem__(self, key, value):
  14. # print(self.__setattr__,key,value)
  15. print(key.start)
  16. print(key.stop)
  17. print(key.step)
  18. #删除key
  19. def __delitem__(self, key):
  20. print(self.__delitem__,key)
  21. obj = lcj("蓝天","蓝色的天空")
  22. # ret = obj[1:4:2] #切片调用:__getitem__方法,并分别打印出:起始位置:1、终止位置:4及字长:2
  23. obj[1:4] = [1,2,3,45,5] #调用__setitem__方法:并分别打印出:起始位置:1、终止位置:4及字长:None
  24. del obj[1:4]

  

    9、__getslice__、__setslice__、__delslice__

  该三个方法用于分片操作,如下:

  1. #!/usr/bin/env python
  2. # -*- coding:utf-8 -*-
  3.  
  4. class Foo(object):
  5.  
  6. def __getslice__(self, i, j):
  7. print '__getslice__',i,j
  8.  
  9. def __setslice__(self, i, j, sequence):
  10. print '__setslice__',i,j
  11.  
  12. def __delslice__(self, i, j):
  13. print '__delslice__',i,j
  14.  
  15. obj = Foo()
  16.  
  17. obj[-1:1] # 自动触发执行 __getslice__
  18. obj[0:1] = [11,22,33,44] # 自动触发执行 __setslice__
  19. del obj[0:2] # 自动触发执行 __delslice__

  10、__iter__

  用于迭代器,之所以列表、字典、元组可以进行for循环,是因为类型内部定义了 __iter__

  1. k = iter([11,23,4,5,6,7,8,])
  2. for i in k: #循环打印出k列表中的各值
  3. print(i)

  11、__new__ 和 __metaclass__

  python中一切都是对象

  如果按照一切事物都是对象的理论:obj对象是通过执行Foo类的构造方法创建,那么Foo类对象应该也是通过执行某个类的 构造方法 创建。

  所以,kw对象是foo类的一个实例,foo类对象是 type 类的一个实例,即:foo类对象 是通过type类的构造方法创建。

  1. class foo:
  2. def __init__(self,name,age):
  3. self.name = name
  4. self.age = age
  5. def lcj(self,):
  6. print("--%s----%d"%(self.name,self.age))
  7. kw = foo('jack',18) #kw是通过foo类实例化的对象
  8. kw.lcj()
  9. print(type(kw)) #输出:<class '__main__.foo'> #表示kw队形是由foo类创建
  10. print(type(foo)) #<class 'type'> #表示foo类对象是由type类创建

  创建类两种方式

  a)普通方式:  

  1. class foo(object):
  2. def lcj(self):
  3. print ("nihao,lcj")
  4. f1 = foo()
  5. f1.lcj()

  b)特殊方式(type类构造函数)  

  1. def lcj():
  2. print('hello xiaoluo')
  3. foo = type('foo',(object,),{'lcj':lcj})
  4. #type第一个参数:类名
  5. #type第二个参数:当前类的基类 object
  6. #type第三个参数:类的成员 'lcj':lcj

  =====》类是由type类实例化产生  

那么问题来了,类默认是由 type 类实例化产生,type类中如何实现的创建类?类又是如何创建对象?

答:类中有一个属性 __metaclass__,其用来表示该类由 谁 来实例化创建,所以,我们可以为 __metaclass__ 设置一个type类的派生类,从而查看 类 创建的过程。

  1. class MyType(type):
  2.  
  3. def __init__(self, what, bases=None, dict=None):
  4. super(MyType, self).__init__(what, bases, dict)
  5.  
  6. def __call__(self, *args, **kwargs):
  7. obj = self.__new__(self, *args, **kwargs)
  8.  
  9. self.__init__(obj)
  10.  
  11. class Foo(object):
  12.  
  13. __metaclass__ = MyType
  14.  
  15. def __init__(self, name):
  16. self.name = name
  17.  
  18. def __new__(cls, *args, **kwargs):
  19. return object.__new__(cls, *args, **kwargs)
  20.  
  21. # 第一阶段:解释器从上到下执行代码创建Foo类
  22. # 第二阶段:通过Foo类创建obj对象
  23. obj = Foo()

五、其他相关

  1、isinstance(obj,lcj)

  检查obj是否是类lcj对象

  1. class Foo(object):
  2. pass
  3. obj = Foo()
  4. ret = isinstance(obj,Foo)
  5. print(ret) #如果obj是Foo类的对象就输出True
  6. # 输出:True

  2、issubclass(sub, super)

  检查sub类是否是super类的派生类(即子类)

  1. class Foo(object):
  2. pass
  3. class lcj(Foo): #lcj子类继承父类Foo
  4. pass
  5. ret = issubclass(lcj,Foo) #如果子类lcj是父类Foo派生类,则返回True,否则False
  6. print(ret)

  3、主动执行父类中的方法,运用super方法

  1. class lcj: #父类
  2. def f1(self):
  3. print('clj.f1')
  4. class xiaoluo(lcj): #子类继承父类lcj
  5. def f2(self):
  6. #主动执行lcj类(父类)中的f1方法
  7. super(xiaoluo,self).f1()
  8. print('xiaoluo.f2')
  9. obj = xiaoluo()
  10. obj.f2()
  11. #输出:clj.f1
  12. # 输出:xiaoluo.f2

  方式二:类+方法名+self关键字  ----》执行父类中的指定的方法

  1. class lcj: #父类
  2. def f1(self):
  3. print('clj.f1')
  4. class xiaoluo(lcj): #子类继承父类lcj
  5. def f2(self):
  6. #主动执行lcj类(父类)中的f1方法
  7. #方式二:类+方法名+self关键字
  8. lcj.f1(self)
  9. obj = xiaoluo()
  10. obj.f2()
  11. #输出:clj.f1

六、异常处理

  

Python_day8_面向对象(多态、成员修饰符、类中特殊方法、对象边缘知识)、异常处理之篇的更多相关文章

  1. Python面向对象之成员修饰符

    对于这些类成员有修饰符 之前定义字段country任何对象都可以访问,是公有的 可以定义为私用属性,只有类内部的方法可以调用,外部不能直接调用,但是可以间接调用 vim day7-10.py #!/u ...

  2. python面向对象之类成员修饰符

      类的所有成员分为: 公有成员,在任何地方都能访问 私有成员,只有在类的内部才能访问 私有成员和公有成员的定义不同:私有成员命名时,前两个字符是下划线.(特殊成员除外,例如:__init__.__c ...

  3. python_way,day8 面向对象【多态、成员--字段 方法 属性、成员修饰符、特殊成员、异常处理、设计模式之单例模式、模块:isinstance、issubclass】

    python_way day8 一.面向对象三大特性: 多态 二.面向对象中的成员 字段.方法属性 三.成员修饰符 四.特殊成员 __init__.__doc__.__call__.__setitem ...

  4. 文成小盆友python-num8 面向对象中的成员,成员修饰符,特殊成员,异常处理,设计模式之单例模式

    本节主要内容: 1.面向对象中的成员 2.成员修饰符 3.特殊成员 4.异常处理 5.设计模式之单例模式 一.面向对象中的成员(类的成员) 类的成员总共可以分为3大类,每类中有不同的分支. 1.总述, ...

  5. C#基础--类/接口/成员修饰符,多态、重载、重写,静态和非静态

    C#基础--类/接口/成员修饰符,多态.重载.重写,静态和非静态 类/接口/成员修饰符 C#修饰符---接口: 接口默认访问符是internal接口的成员默认访问修饰符是public C#修饰符--类 ...

  6. python学习day20 面向对象(二)类成员&成员修饰符

    1.成员 类成员 类变量 绑定方法 类方法 静态方法 属性 实例成员(对象) 实例变量 1.1实例变量 类实例化后的对象内部的变量 1.2类变量 类中的变量,写在类的下一级和方法同一级. 访问方法: ...

  7. Python学习:17.Python面向对象(四、属性(特性),成员修饰符,类的特殊成员)

    一.属性(特性) 普通方法去执行的时候,后面需要加括号,特性方法执行的时候和静态字段一样不需要不需要加括号. 特性方法不和字段同名. 特性方法不能传参数. 在我们定义数据库字段类的时候,往往需要对其中 ...

  8. Python菜鸟之路:Python基础-类(2)——成员、成员修饰符、异常及其他

    三大成员 在Python的面向对象中,主要包括三大成员:字段.方法.属性 字段 类成员的字段又可分为普通字段.静态字段,他们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同,代码示例如下: ...

  9. Python学习 :面向对象 -- 成员修饰符

    成员修饰符 两种成员 - 公有成员 - 私有成员, __字段名 - 无法直接访问,只能通过内部方法来间接访问私有成员 简例:公有成员与私有成员  class Info: country = '中国' ...

随机推荐

  1. 让一个小Div(子)在大Div(父)中垂直水平都居中

    方法1: .parent {          width:800px;          height:500px;          border:2px solid #000;          ...

  2. jQuery基础学习笔记(1)

    --------2.0以上版本体积更小. --------CDN  内容分发网络(Content delivery network或Content distribution network,常简写成C ...

  3. Unity3D ShaderLab 透明裁剪着色器

    Unity3D ShaderLab 透明裁剪着色器 上一篇,我们介绍了使用Alpha实现透明的手法,其实Unity为我们的#pragma提供了另一种参数,是我们能做出更高效 简单的透明效果,也就是裁剪 ...

  4. 使用Office 365 试用账户 体验Office 365功能

    首先,需要申请Office 365 Enterprise E3版本的试用账户. 在浏览器中,输入以下地址,然后回车: http://products.office.com/en-us/business ...

  5. Smart210学习记录-----中断

    1. OVERVIEW OF VECTORED INTERRUPT CONTROLLER(概述向量中断控制器) 主要有4个VIC,4个TZIC还有一个很特殊的ARM PrimeCell PL192.主 ...

  6. magento 多域名多店铺

    事前指导 我们使用的就是parked domain ,将你要添加的域名指向你的现有magento 文件根目录. 就像预习中提到的,我们有个magento站域名为one.com ,添加新的域名two.c ...

  7. 机器学习技法-GBDT算法

    课程地址:https://class.coursera.org/ntumltwo-002/lecture 之前看过别人的竞赛视频,知道GBDT这个算法应用十分广泛.林在第八讲,简单的介绍了AdaBoo ...

  8. 225. Implement Stack using Queues

    代码如下: class MyStack { // Push element x onto stack. Queue<Integer> queue=new ArrayDeque<> ...

  9. raido 赋值第一次成功,然后就赋值不显示

    $("#id").attr("checked",true); //显示出现问题,第一次成功 $("#id").prop("chec ...

  10. CSS3 transform的skew属性值图文详解

    我刚刚接触transform的skew属性值时一头雾水,根本不知道种东西到底是咋变的.上网查,各个网站上也只说这个使用来做扭曲变换的,具体是咋变的就是不说....无奈我只好自己研究了,现把研究结果共享 ...