一、面向对象学习

1、面向对象介绍

2、创建一个类

3、实例变量和类变量

4、析构函数

5.私有属性&私有方法

6、继承

7、多态

8、类的特殊方法

9、反射

面向对象编程

OOP编程是利用“类”和“对象”来创建各种模型来实现对真实世界的描述,使用面向对象编程的原因一方面是因为它可以使程序的维护和扩展变得更简单,并且可以大大提高程序开发效率 ,另外,基于面向对象的程序可以使它人更加容易理解你的代码逻辑,从而使团队开发变得更从容。

初识class类

  1. 一个类即是对一类拥有相同属性的对象的抽象、蓝图。原型。在类中定义了这些对象的都具备的属性、共同的方法。

面向过程编程和面向对象编程:

  1. 面向过程编程:使用一系列的指令告诉计算机怎么一步步执行
  2. 基本设计思路就是程序一开始是着手解决一个大的问题,然后把一个大的问题分解成很多小问题或子过程
  3. 面向对象编程:
  4. OOP编程是利用“类”和“对象”来创建各种模型来实现对真实世界的描述
  5. 世界万物皆对象。
  6. 只要是对象,就肯定属于某种类
  7. 只要是对象,就肯有属性

objiect对象:

  1. 一个对象即是一个类的实例化后的实例,一个类可以实例化多个对象,每个对象亦可以有不同的属性

特性:

  封装

  继承

  多态

encapsulation封装:

  在类中对数据的赋值、内部调用对外部用户是透明的,这使类变成了一个胶囊或容器,里面包含着类的数据和方法,封装可以隐藏实现细节,使得代码模块化,就是用户不需要知道类的内部是怎样做的,只需要知道它的功能。

inheritance继承:

  一个类可以派生出子类,在这个父类里面定义的属性、方法自动被子类继承

名词术语:

  • 类(Class):

  用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。

  • 类变量

  类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。

  • 对象

  一个对象即是一个类的实例化后的实例,一个类必须经过实例化后方可在程序中调用,一个类可以实例化多个对象,每个对象亦可以有不同的属性

  • 实例变量

  定义在方法中的变量,只作用于当前实例的类

  • 方法

   类中定义的函数。(动态属性)

  • 属性

  类变量、实例变量、方法都是属性,变量是静态属性,方法是动态属性

  • 实例化

  创建一个类的实例,类的具体对象。

类的语法:

  用class语句来创建一个新类,class之后为类的名称并以冒号结尾

  1. class liangwei:
  2. print("我是一个类")

术语讲解

1、构造方法

  1. class Role(object): #定义一个类
  2. def __init__(self): #初始化,构造方法,调用类的时候自动执行的函数
  3. pass

上面的这个__init__()叫做初始化方法(或构造方法), 在类被调用时,这个方法(虽然它是函数形式,但在类中就不叫函数了,叫方法)会自动执行,进行一些初始化的动作。

属性

  1. __author__ = 'lw'
  2.  
  3. class Role(object):
  4. def __init__(self,name,role,weapon,life_value=100,money=15000): ##定义一个类, class是定义类的语法,Role是类名,(object)是新式类的写法
  5. self.name = name              ##初始化函数,在生成一个角色时要初始化的一些属性就填写在这里
  6. self.role = role              ####self.name = r1.name
  7. self.weapon = weapon
  8. self.life_value = life_value
  9. self.money = money
  10.  
  11. def shot(self):
  12. print("shooting...")
  13.  
  14. def got_shot(self):
  15. print("ah...,I got shot...")
  16.  
  17. def buy_gun(self,gun_name):
  18. print("just bought %s" %gun_name)
  19.  
  20. r1 = Role('Alex','police','AK47') #生成一个角色,也即是生成一个实例(对象)
  21. r2 = Role('Jack','terrorist','B22') #生成一个角色,生成一个实例(对象)
    我们看到,上面的创建角色时,我们并没有给__init__传值,程序也没未报错,是因为,类在调用它自己的__init__(…)时自己帮你给self参数赋值了,
r1 = Role('Alex','police','AK47’) #此时self 相当于 r1 ,  Role(r1,'Alex','police','AK47’)
r2 = Role('Jack','terrorist','B22’)#此时self 相当于 r2, Role(r2,'Jack','terrorist','B22’)
  1.  
   

例2:

  

  1. #!/usr/bin/env python
  2. #_*_ coding:utf-8 _*_
  3. #_*_coding:utf-8_*_
  4. class Dog:
  1. n = 123 #类变量,公用的属性
  1.   def __init__(self,name): #构造函数   
  2.  
  3.   #self代表d1,self就是为了接受d1,d1(self)其实就是接收的变量值的内存地址,下面函数调用(self)的时候就是把变量传进去(内存地址)
  4.  
  5.   #self:谁调用就是指谁(d1或者d2或者d3) #d1 = Dog(“al”)---->Dog(“d1”,”al”),
        self.name = name #实例变量(静态属性),赋值给实例,作用域就是实例本身
        
      def bulk(self): #self接收d1(Dog)
        “””” Bulk:类的方法(动态属性) ”””
  6.  
  7.     print("%s 汪~汪~汪" %(self.name)) #self.name ===d1.name
    d1 = Dog("旺旺") #只是生成一个dog,并没有动作,旺旺是传给了类里面init函数里的变量
    d1.name = “旺旺2 #可以改名
    d1.fafagagag = test #可以添加一个新的属性
    del d1.name 删除d1name属性,下面就不能调用了
    d2 = Dog("小黑")
    d3 = Dog("豆豆")
    d1.bulk() #动作 d2.bulk()
  8.  
  9. #执行输出: # 旺旺 汪~汪~汪 # 小黑 汪~汪~汪
  10.  
  11. #注:变量的顺序,现找实例变量,后找类变量,如果有实例变量就用实例变量,如果没有实例变量,就用类变量

2、析构函数(方法)

  在实例释放、销毁的时候自动执行的,通常用于做一些收尾工作, 如关闭一些数据库连接,关闭打开的临时文件

  1. def __del__(self): #析构函数,收尾工作,自动执行
  2. pass

例1:

  1. #_*_ coding:utf-8 _*_
  2. class Role(object):
  3. def __init__(self,name,role,weapon,life_value=100,money=15000):
  4. #构造函数
  5. #在实例化时做一些类的初始化的工作
  6. self.name = name
  7. self.role = role
  8. self.weapon = weapon
  9. self.life_value = life_value
  10. self.money = money
  11. def __del__(self): #析构函数,收尾工作,自动执行
  12. print("%s 死了"%self.name)
  13. def shot(self):
  14. print("shooting...")
  15.  
  16. def got_shot(self):
  17. print("%s: ah...,I got shot..."%self.name)
  18.  
  19. def buy_gun(self,gun_name):
  20. print("just bought %s" %gun_name)
  21.  
  22. r1 = Role('Alex','police','AK47') #生成一个角色
  23. r1.buy_gun("AAA")
  24. r1.got_shot()
  25. r2 = Role('Jack','terrorist','B22') #生成一个角色
  26. r2.got_shot()
  27.  
  28. 执行结果:
  29. just bought AAA
  30. Alex: ah...,I got shot... #在这析构函数并没有执行,因为程序还在执行,r1实例还在内存中,没有释放! 如果想中枪就死,需要在r1执行完后(r1.got_shot()后面)加上del r1
  31. Jack: ah...,I got shot...
  32. Alex 死了
  33. Jack 死了

私有属性&&私有方法

  私有属性:只能内部(类的内部)调用,外面调用不了(r1调用不了)

  私有方法:和私有方法是一样的。

  1. # _*_ coding:utf-8 _*_
  2. __author__ = 'XS'
  3. #_*_ coding:utf-8 _*_
  4. class Role(object):
  5. def __init__(self,name,role,weapon,life_value=100,money=15000):
  6. #构造函数
  7. #在实例化时做一些类的初始化的工作
  8. self.name = name
  9. self.role = role
  10. self.weapon = weapon
  11. self.__life_value = life_value #私有属性
  12. self.money = money
  13. def __shot(self): #私有方法
  14. print("shooting...")
  15. def show_status(self): #只能这样调用
  16. print("%s:life_vale"%self.__life_value)
  17. def got_shot(self):
  18. self.__shot() #调用私有方法
  19. r1 = Role('A','police','AK47') #生成一个角色)
  20. r1.got_shot()
  21. #r1._Role__shot()
  22. print(r1.show_status())
  23. r2 = Role('Jack','terrorist','B22') #生成一个角色
  24. r2.got_shot()

3、静态方法

  1. # _*_ coding:utf-8 _*_
  2. __author__ = 'XS'
  3. class Dog(object):
  4. def __init__(self,name,food):
  5. self.name = name
  6. self.food = food
  7. # @staticmethod
  8. #静态方法,使下面的类的方法变成一个单纯的函数(使函数跟类没什么关系了,只是还是需要这个类调用)
  9. #下面的函数不能调用类的变量,也不能调用self。
  10. # @classmethod #类方法
  11. def eat(self):
  12. print("%s is eating %s"%(self.name,self.food))
  13. # def eat():
  14. # print("%s is eating %s"%("A","food"))
  15. d = Dog("A","B")
  16. d.eat()
  17. # d = Dog("A","B")
  18. # d.eat()

4、类方法:只能访问类变量,不能访问实例变量

  1. # _*_ coding:utf-8 _*_
  2. __author__ = 'XS'
  3. class Dog(object):
  4. # name = "zs"
  5. # food = "qiezi"
  6. def __init__(self,name,food):
  7. self.name = name
  8. self.food = food
  9. # @classmethod #类方法,只能访问类变量,不能访问实例变量
  10. def eat(self):
  11. print("%s is eating %s"%(self.name,self.food))
  12. d = Dog("A","B")
  13. d.eat()

5、属性方法

  把一个方法变成一个静态属性,(成为一个属性后不能通过加括号调用)

  1. # _*_ coding:utf-8 _*_
  2. __author__ = 'XS'
  3. class Dog(object):
  4. def __init__(self,name):
  5. self.name = name
  6. # self.__food = None
  7. def eat(self):
  8. print("%s is eating %s"%(self.name,""))
  9. # @property # 属性方法,变成一个属性后就不能通过括号传参数了
  10. # def eat(self):
  11. # print("%s is eating %s"%(self.name,self.__food))
  12. # @eat.setter #和属性方法对应,用于给属性方法传参数
  13. # def eat(self,food):
  14. # print "set to food:",food
  15. # self.__food = food
  16. # @eat.deleter
  17. # def eat(self):
  18. # del self.__food
  19. # print("delete")
  20.  
  21. d = Dog("A")
  22. d.eat()
  23. # d.eat
  24. # d.eat = "baozi"
  25. # d.eat
  26. #
  27. # del d.eat #属性方法默认不能删除,需要@eat.deleter
  28. # d.eat

继承

例1:

  1. class People:
  2. def __init__(self,name,age):
  3. self.name = name
  4. self.age = age
  5. def eat(self):
  6. print("%s is eating...."%self.name)
  7. def talk(self):
  8. print("%s is talking..."%self.name)
  9. def sleep(self):
  10. print("%s is sleeping...."%self.name)
  11. class Man(People): #继承People类
  12. pass
  13. m1 = Man("A","") #因为Man是继承People,所以调用Man的时候需要传和People一样的参数
  14. m1.eat()

例2:

  1. #_*_ coding:utf-8 _*_
  2. class People(object):
  3. def __init__(self,name,age):
  4. self.name = name
  5. self.age = age
  6. def eat(self):
  7. print("%s is eating...."%self.name)
  8. def talk(self):
  9. print("%s is talking..."%self.name)
  10. def sleep(self):
  11. print("%s is sleeping...."%self.name)
  12. class Man(People):
  13. def __init__(self,name,age,money): #重构父类方法
  14. #因为继承的父类People,父类里面有name和age属性,所以这里也要加
  15. #实例化的时候传的参数先到这里
  16. # People.__init__(self,name,age) #把父类的执行一遍(调用父类),经典类写法
  17. super(Man,self).__init__(name,age) #调用父类,和上面的一样,新式类写法
  18. self.money = money #name和age 都在父类里面定义了,这里只需要money
  19. print("%s 一出生就有%s money"%(self.name,self.money))
  20. def piao(self):
  21. print("%s is piaoing....."%self.name)
  22. class Woman(People):
  23. def get_birth(self):
  24. print("%s is born a baby...."%self.name)
  25. m1 = Man("A","","")
  26. m1.eat()
  27. m1.piao()
  28.  
  29. w1 = Woman("B",26)
  30. w1.get_birth()

多继承

例1:

  1. #_*_ coding:utf-8 _*_
  2. class People(object):
  3. def __init__(self,name,age):
  4. self.name = name
  5. self.age = age
  6. def eat(self):
  7. print("%s is eating...."%self.name)
  8. def talk(self):
  9. print("%s is talking..."%self.name)
  10. def sleep(self):
  11. print("%s is sleeping...."%self.name)
  12. class Relation(object):
  13. def make_friends(self,obj):
  14. print("%s is making friends with %s" %(self.name,obj.name)) #name在下面类里面继承父类的时候传进去
  15. class Man(People,Relation): #在Man构造的时候生成了name,下面调用的时候先执行的Man,然后在执行父类的方法
  16. #子类有构造函数(__init__),所以继承的顺序没有关系,如果子类没有构造函数,继承的顺序是有关系的,因为没有构造函数变量就会传到父类里面,一个父类里面没有就去另一个父类里面找
  17. def __init__(self,name,age,money): #重构父类方法
  18. #因为继承的父类People,父类里面有name和age属性,所以这里也要加
  19. #实例化的时候传的参数先到这里
  20. # People.__init__(self,name,age) #把父类的执行一遍(调用父类),经典类写法
  21. super(Man,self).__init__(name,age) #调用父类,和上面的一样,新式类写法
  22. self.money = money #name和age 都在父类里面定义了,这里只需要money
  23. print("%s 一出生就有%s money"%(self.name,self.money))
  24. def piao(self):
  25. print("%s is piaoing....."%self.name)
  26. class Woman(People,Relation):
  27. def get_birth(self):
  28. print("%s is born a baby...."%self.name)
  29. m1 = Man("A","","")
  30. w1 = Woman("B","") #Woman继承的People,所以需要传2个参数
  31. m1.make_friends(w1) #obj = w1 --》0bj.name == w1.name

经典类和新式类的区别

广度优先:先找D,D没有就找B,B没有找C,C没有找A

深度优先:先找D,D没有就找A,A没有在去找C

  1. #_*_ coding:utf-8 _*_
  2.  
  3. class A:
  4.  
  5. def __init__(self):
  6.  
  7. print("A")
  8.  
  9. class B(A): #B继承A
  10.  
  11. pass
  12.  
  13. # def __init__(self):
  14.  
  15. # print("B")
  16.  
  17. class C(A): #C继承A
  18.  
  19. pass
  20.  
  21. # def __init__(self):
  22.  
  23. # print("C")
  24.  
  25. class D(B,C): #D继承B,C
  26.  
  27. pass
  28.  
  29. # def __init__(self):
  30.  
  31. # print("D")
  32.  
  33. obj = D()

Python2:经典类是按深度优先查询,新式类是按广度优先继承的

pythony3: 经典类和新式类都是统一按广度优先来继承的

继承实例(学校)

实例功能,教师教学,学生缴费

  1. # _*_ coding:utf-8 _*_
  2. __author__ = 'XS'
  3. class School(object):
  4. def __init__(self,name,addr):
  5. self.name = name
  6. self.addr = addr
  7. self.students = []
  8. self.teachers = []
  9. self.staffs = []
  10. def enroll(self,stu_obj):
  11. print("为学员%s办理注册手续"%stu_obj.name) #stu_obj是个实例,学员需要实例化,实例化后就可以得到名字
  12. self.students.append(stu_obj) #添加到列表中的都是实例,打引:print(stu_obj[0].name)
  13. def hire(self,staff_obj):
  14. self.staffs.append(staff_obj) #添加到列表中的都是实例,打引列表中的值:print(staff_obj[0].name==staff_obj.name)
  15. print("雇佣新员工%s" %staff_obj.name)
  16. class SchoolMember(object):
  17. def __init__(self,name,age,sex):
  18. #学生和老师类都需要继承schoolMember类,老师和学生都有name、age。。。
  19. #下面老师和学生类继承schoolMember类,就可以少写属性了(self.name = name)
  20. self.name = name
  21. self.age = age
  22. self.sex = sex
  23. def tell(self):
  24. pass
  25. class Teacher(SchoolMember):
  26. def __init__(self,name,age,sex,salary,course): #重构父方法,教师除了name等,还有salary和course(课程)
  27. super(Teacher,self).__init__(name,age,sex) #继承父类已经实现了的(变量/属性)
  28. self.salary = salary #自己的变量(属性)
  29. self.course = course
  30. def tell(self): #重构tell方法
  31. print('''
  32. ---- info of Teacher:%s ----
  33. name:%s
  34. Age:%s
  35. Sex:%s
  36. Salary:%s
  37. Course:%s
  38. '''%(self.name,self.name,self.age,self.sex,self.salary,self.course))
  39.  
  40. def teach(self): #教师的特性方法
  41. print("%s is teaching course [%s]"%(self.name,self.course))
  42.  
  43. class Student(SchoolMember):
  44. def __init__(self,name,age,sex,stu_id,grade):
  45. super(Student,self).__init__(name,age,sex) ##继承父类已经实现了的(变量),
  46. self.stu_id = stu_id #自己的变量(属性)
  47. self.grade = grade
  48. def tell(self): #重构tell方法
  49. print('''
  50. ---- info of Student:%s ----
  51. name:%s
  52. Age:%s
  53. Sex:%s
  54. Stu_id:%s
  55. Grade:%s
  56. '''%(self.name,self.name,self.age,self.sex,self.stu_id,self.grade))
  57. def pay_tuition(self,amount): #定义学生自己的方法
  58. print("%s has paid tuition for $ %s"%(self.name,amount))
  59.  
  60. #开始实例化
  61. #先实例化一个学校
  62. school = School("清华","中关村") #School类里面构造函数的时候需要2个参数
  63.  
  64. t1 = Teacher("Oldboy",56,"Man",20000,"Linux")
  65. t2 = Teacher("Alex",22,"Man",3000,"Python")
  66.  
  67. s1 = Student("A",30,"MF",1001,"Python")
  68. s2 = Student("B",20,"Woman",1002,"Linux")
  69.  
  70. t1.tell()
  71. s1.tell()
  72. school.hire(t1)
  73. school.enroll(s1)
  74. school.enroll(s2)
  75.  
  76. print(school.students)
  77. print(school.staffs)
  78.  
  79. school.staffs[0].teach()
  80.  
  81. for stu in school.students:
  82. stu.pay_tuition(5000)

多态

一种接口,多种实现

例:

  1. # _*_ coding:utf-8 _*_
  2. __author__ = 'XS'
  3. class Animal: #定义一个动物类
  4. def __init__(self,name):
  5. self.name = name
  6. # def talk(self):
  7. # pass
  8. # @staticmethod #静态方法
  9. # def duotai(obj):
  10. # obj.talk()
  11. class Cat(Animal):
  12. def talk(self):
  13. print("%s is miao"%self.name)
  14. class Dog(Animal):
  15. def talk(self):
  16. print("%s is wang"%self.name)
  17.  
  18. # def duotai(obj): #定义一个多态接口,传一个obj参数
  19. # obj.talk()
  20. d = Dog("A")
  21. d.talk()
  22.  
  23. c = Cat("B")
  24. c.talk()
  25.  
  26. #
  27. # duotai(d)
  28. # duotai(c)
  29.  
  30. # Animal.duotai(d)
  31. # Animal.duotai(c)

类的特殊方法

1. __doc__  表示类的描述信息

  1. # _*_ coding:utf-8 _*_
  2. __author__ = 'XS'
  3. class Foo:
  4. """类的描述信息,就是__doc__"""
  5. def func(self):
  6. pass
  7. print Foo.__doc__

2. __module__ 和  __class__ 

  1. __author__ = 'XS'
  2. class C:
  3. def __init__(self):
  4. pass
  5. ############
  6. from lw.tete import C
  7.  
  8. A = C()
  9. print(A.__module__) #输出C这个模块是在哪个路径导入的
  10. print(A.__class__) #输出A是哪个类实例化的

3. __init__ 构造方法,通过类创建对象时,自动触发执行。

4.__del__

5. __call__ 对象后面加括号,触发执行

  1. #__call__
  2. # 注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()
  3. class Dog:
  4. def __init__(self,name):
  5. self.name = name
  6. def bulk(self):
  7. print("%s 汪~汪~汪" %(self.name))
  8. def __call__(self, *args, **kwargs):
  9. print "I am call",args,kwargs
  10. d1 = Dog("旺旺")
  11. d1("aaa","bbb","cccc")

6. __dict__ 查看类或对象中的所有成员

  1. # _*_ coding:utf-8 _*_
  2. __author__ = 'XS'
  3. class Province:
  4. country = 'China'
  5. def __init__(self, name, count):
  6. self.name = name
  7. self.count = count
  8. def func(self, *args, **kwargs):
  9. print 'func'
  10. # 获取类的成员,即:静态字段、方法、
  11. print Province.__dict__
  12. # obj1 = Province('HeBei',10000)
  13. # print obj1.__dict__
  14. # 获取 对象obj1 的成员
  15. obj2 = Province('HeNan', 3888)
  16. # print obj2.__dict__
  17. # 获取 对象obj1 的成员

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

python3中使用,python建议使用__unicode__

  1. # _*_ coding:utf-8 _*_
  2. __author__ = 'XS'
  3. # _*_ coding:utf-8 _*_
  4. __author__ = 'XS'
  5. #_*_ coding:utf-8 _*_
  6. class Role(object):
  7. def __init__(self,name,role,weapon,life_value=100,money=15000):
  8. self.name = name
  9. self.role = role
  10. self.weapon = weapon
  11. self.life_value = life_value
  12. self.money = money
  13. def shot(self):
  14. print("shooting...")
  15. def got_shot(self):
  16. print("%s: ah...,I got shot..."%self.name)
  17. def buy_gun(self,gun_name):
  18. print("just bought %s" %gun_name)
  19. # def __str__(self):
  20. # print("name is %s"%self.name)
  21. # return "name is %s"%self.name
  22.  
  23. r1 = Role("A","P","Ak47")
  24. print(r1)

8.__getitem__、__setitem__、__delitem__

用于索引操作,如字典。以上分别表示获取、设置、删除数据

  1. # _*_ coding:utf-8 _*_
  2. __author__ = 'XS'
  3. #把这个实例变成字典
  4. class Foo(object):
  5. def __init__(self):
  6. self.data = {}
  7. def __getitem__(self, key):
  8. print('__getitem__',key) #('__getitem__', 'name')
  9. return self.data.get(key)
  10. def __setitem__(self, key, value):
  11. print('__setitem__',key,value)
  12. self.data[key] = value
  13. def __delitem__(self, key):
  14. print('__delitem__',key)
  15.  
  16. obj = Foo() #实例化后,就成了字典
  17. obj["name"] = "lw" #可以像字典一样赋值,自动触发执行 __setitem__
  18. result = obj['name'] # 自动触发执行 __getitem__
  19. print(result)
  20. print(obj.data) #打印这个字典
  21. del obj['name'] #只是触发__delitem__,并没有真的删除,要想删除在__delitem__这个函数下面删除,如果不想让用户删除某些key,可以加判断
  22. print(obj.data)
  23. # del obj['k1']

9. __new__ \ __metaclass__

  1. # _*_ coding:utf-8 _*_
  2. __author__ = 'XS'
  3. class Foo(object):
  4. def __init__(self,name):
  5. self.name = name
  6.  
  7. f = Foo("lw")

上述代码中,obj 是通过 Foo 类实例化的对象,其实,不仅 obj 是一个对象,Foo类本身也是一个对象,因为在Python中一切事物都是对象

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

  1. print type(f) # 输出:<class '__main__.Foo'> 表示,obj 对象由Foo类创建
  2. print type(Foo) # 输出:<type 'type'> 表示,Foo类对象由 type 类创建

那么创建类就有两种方式

a)普通方式:

  1. class Foo(object):
  2. def __init__(self,name):
  3. self.name = name

b)特殊方式:

  1.  
  1. def func(self):
    print("hello xs")
    Foo = type('Foo',(object),{'fc':func}) #Foo:类名,object:新式类,fc:key,func函数
  2.  
  3. print(type(Foo))
  4.  
  5. f = Foo()
    f.fc()
  1. #type第一个参数:类名 #type第二个参数:当前类的基类 #type第三个参数:类的成员
  2.  
  3. SO,类是由type类实例化产生的
  1. #类的起源,类的底层----------一切皆对象,类也是对象
  1. def func(self):
  2. print("hello xs %s"%self.name)
  3. def __init__(self,name,age):
  4. self.name = name
  5. self.age = age
  6. Foo = type('Foo',(),{'fc':func,'__init__':__init__})
  7. f = Foo("A","")
  8. f.fc()

反射

通过字符串映射或修改程序运行时的状态、属性、方法, 有以下4个方法

hasattr:判断object中有没有一个name字符串对应的方法或属性

getattr:根据字符串去获取对象里的方法对应的内存地址

setattr :s equivalent to ``x.y = v''

  1. # _*_ coding:utf-8 _*_
  2. __author__ = 'XS'
  3. def bulk(self): #这里会将函数设置成类里面的方法
  4. print("%s is bulking"%self.name)
  5. class Dog(object):
  6.  
  7. def __init__(self,name):
  8. self.name = name
  9. def eat(self,age):
  10.  
  11. print("%s is eating.."%self.name)
  12.  
  13. d = Dog("金毛")
  14. # d.eat()
  15. choice = raw_input(">>>:").strip()
  16. # d.choice 想实现这种调用,根据用户输入调用方法,但是不能这么写,因为choic是个字符串
  17. print(hasattr(d,choice)) #查看类中是否有用户输入的方法或者属性,有打印True,没有打印False
  18. # print(getattr(d,choice)) #这样会打印这个方法的内存地址,加上()就调用了
  19. # getattr(d,choice)() #调用
  20. #------------------------------
  21. # print(d.name)
  22. # setattr(d,"name",choice)
  23. # print(d.name)
  24. #-------------------------------
  25. # setattr(d,choice,"22")
  26. # print(getattr(d,choice))
  27. # print(hasattr(d,choice))
  28. #------------------------------
  29. #动态添加变量
  30. # if hasattr(d,choice):
  31. # getattr(d,choice)
  32. # else:
  33. # setattr(d,choice,"ccc")
  34. # V = getattr(d,choice)
  35. # print(V)
  36. #---------------------------
  37. #动态设置方法,无论用户输入什么,都不会报错,都可以调用方法
  38. # if hasattr(d,choice):
  39. # getattr(d,choice)
  40. # else:
  41. # setattr(d,choice,bulk) #d.talk == bulk
  42. # func = getattr(d,choice) #获取choic的内存地址
  43. # func(d)
  44.  
  45. # ----------------------
  46. # print(hasattr(d,choice))
  47. # getattr(d,choice)()
  48. # print(d.name)
  49. # if hasattr(d,choice):
  50. # delattr(d,choice)
  51. # else:
  52. # print("dont")
  53. # print(d.name)
  54. # delattr(d,choice)
  55. # if hasattr(d,choice):
  56. # getattr(d,choice)()
  57. #
  58. # else:
  59. # # print("没有这个方法")

练习

角色:学校、学员、课程、讲师
要求:
1. 创建北京、上海 2 所学校
2. 创建linux , python , go 3个课程 , linux\py 在北京开, go 在上海开
3. 课程包含,周期,价格,通过学校创建课程 
4. 通过学校创建班级, 班级关联课程、讲师
5. 创建学员时,选择学校,关联班级
5. 创建讲师角色时要关联学校, 
6. 提供两个角色接口
6.1 学员视图, 可以注册, 交学费, 选择班级,
6.2 讲师视图, 讲师可管理自己的班级, 上课时选择班级, 查看班级学员列表 , 修改所管理的学员的成绩 
6.3 管理视图,创建讲师, 创建班级,创建课程

python学习之路-day6-面向对象的更多相关文章

  1. python学习之路-8 面向对象之进阶

    上篇内容回顾和补充 面向对象三大特性 封装 继承 多态 在python中没有多态的概念 变量的类型允许为多种数据类型称之为多态 # c#/java中的多态 # 伪代码 def func(int arg ...

  2. Python学习之路10☞面向对象进阶

    一 isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的对象 1 class Foo(objec ...

  3. Python学习之路9☞面向对象的程序设计

    一 面向对象的程序设计的由来 见概述:http://www.cnblogs.com/linhaifeng/articles/6428835.html 二 什么是面向对象的程序设计及为什么要有它 面向过 ...

  4. ql的python学习之路-day6

    字节编码: 这一节主要学习的是各种编码模式的相互转换,另外插两句话,今天的心情不是特别好,又没控制好自己的情绪,以后要心存阳光,好好的对待生活和身边的人. 废话不多说了直接贴码: #!/usr/bin ...

  5. Python学习之路——类-面向对象编程

    类 面向对象编程 通过类获取一个对象的过程 - 实例化 类名()会自动调用类中的__init__方法 类和对象之间的关系? 类 是一个大范围 是一个模子 它约束了事务有哪些属性 但是不能约束具体的值 ...

  6. (转)Python之路,Day6 - 面向对象学习

    本节内容:   面向对象编程介绍 为什么要用面向对象进行开发? 面向对象的特性:封装.继承.多态 类.方法.     引子 你现在是一家游戏公司的开发人员,现在需要你开发一款叫做<人狗大战> ...

  7. python学习之路------你想要的都在这里了

    python学习之路------你想要的都在这里了 (根据自己的学习进度后期不断更新哟!!!) 一.python基础 1.python基础--python基本知识.七大数据类型等 2.python基础 ...

  8. python学习之路-day2-pyth基础2

    一.        模块初识 Python的强大之处在于他有非常丰富和强大的标准库和第三方库,第三方库存放位置:site-packages sys模块简介 导入模块 import sys 3 sys模 ...

  9. Python学习之路-Day2-Python基础3

    Python学习之路第三天 学习内容: 1.文件操作 2.字符转编码操作 3.函数介绍 4.递归 5.函数式编程 1.文件操作 打印到屏幕 最简单的输出方法是用print语句,你可以给它传递零个或多个 ...

  10. Python学习之路-Day2-Python基础2

    Python学习之路第二天 学习内容: 1.模块初识 2.pyc是什么 3.python数据类型 4.数据运算 5.bytes/str之别 6.列表 7.元组 8.字典 9.字符串常用操作 1.模块初 ...

随机推荐

  1. VS有效序列号

    VS2005 : KYTYH-TQKW6-VWPBQ-DKC8F-HWC4J VS2008 : PYHYP-WXB3B-B2CCM-V9DX9-VDY8T VS2010 : YCFHQ-9DWCY-D ...

  2. java自编时间工具类

    package timeTools; import java.text.ParseException; import java.text.SimpleDateFormat; import java.u ...

  3. VideoToolbox硬件编解码H.264视频流错误码

    如果你不能找到在VTD中的错误代码我决定只包括他们在这里. (同样,所有这些错误,并更可以在里面VideoToolbox在Project Navigator中找到.本身).  您将获得无论是在VTD中 ...

  4. prolog --寻找neni (2)

    混合查询 我们可以把简单的查询连接起来,组成复杂的查询. ?- location(X,kitchen),edible(X). 简单查询只有一个目标,而混合查询可以把这些目标连接起来.从而进行较为复杂的 ...

  5. php用simplexml来操作xml

    <?php$username = 'zhansan';if (!file_exists('001.xml')){ $fp = fopen('001.xml', 'w'); $xmlContent ...

  6. PostgreSQL系列一:PostgreSQL简介与安装

    一.PostgreSQL简介     1.1 PostgreSQL概述             PostgreSQL数据库是目前功能最强大的开源数据库,支持丰富的数据类型(如JSON和JSONB类型. ...

  7. Android Studio中清单文件改versionCode和versionName没效果的原因

    在Android Studio中,项目的versionCode 和versionName 的控制不是在AndroidManifest.xml清单文件中更改的,而是在项目的build.gradle中更改 ...

  8. java.lang.ClassCastException: android.view.AbsSavedState$1 cannot be cast to android.widget.ProgressBar$SavedState

    java.lang.ClassCastException: android.view.AbsSavedState$1 cannot be cast to android.widget.Progress ...

  9. WPF开发经验

    UpdateSourceTrigger 0.在一个项目中在用到绑定的时候一直有一个问题,虽然设置了Mode=TwoWay,界面的值修改了,但是后天绑定的值没有变化.最终发现了问题,在于UpdateSo ...

  10. 循序渐进Python3(十一) --3--  web之dom

    DOM                  文档对象模型(Document Object Model,DOM)是一种用于HTML和XML文档的编程接口.它给文档提供了一种结构化的表示方法,可以改变文档的 ...