面向对象编程

面向对象编程(Object Oriented Programming,OOP,面向对象程序设计)

一、编程类型

面向过程编程:根据业务逻辑从上到下写垒代码,分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。

函数式编程:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可

面向对象编程:对函数进行分类和封装,把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。

二、类和对象

面向对象编程需要使用 “类” 和 “对象” 来实现

类就是一个模板,模板里可以包含多个函数,函数里实现一些功能

对象则是根据模板创建的实例,通过实例对象可以执行类中的函数

 1 class role(object):  #创建一个类,类名role,(object)新式类的写法
 2     ac = None
 3     def __init__(self,name,role,weapon,life_value=100):  #初始化函数,在生成一个角色时要初始化的一些属性就填写在这里
 4         self.name = name
 5         self.role = role
 6         self.weapon = weapon
 7         self.life_value = life_value
 8     def buy_weapon(self,weapon):
 9         print("%s is buying [%s]" %(self.name,weapon))
10         self.weapon = weapon
11 
12 p1 = role("nima",'police',"B11",90)  #创建对象,自动把参数传给Role下面的__init__(...)方法
13 t1 = role("nimei",'terrorist',"B10",100)  #生成一个角色,相当于 t1, role(t1,'nimei','terrorist','B10',100)
14 p1.buy_weapon("AK47")  #python 会自动帮你转成 role.buy_weapon(p1,”B21")
15 t1.buy_weapon("B51")
16 
17 p1.ac = "china brand"
18 role.ac = "us brand"
19 print("p1:",p1.life_value,p1.ac)
20 print("t1:",t1.weapon,t1.ac)

__init__()叫做初始化方法(或构造方法), 在类被调用时,这个方法(虽然它是函数形式,但在类中就不叫函数了,叫方法)会自动执行,进行一些初始化的动作,所以我们这里写的__init__(self,name,role,weapon,life_value=100)就是要在创建一个角色时给它设置这些属性

三、面向对象三大特性

1.封装

封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。

将内容封装到某处

1 class foo:
2     def __init__(self,name,age):
3         self.name = name
4         self.age = age
5 
6 obj = foo('haha',22)  #将haha和22分别封装到obj的name和age属性中

调用被封装的内容

1 class foo:
2     def __init__(self,name,age):
3         self.name = name
4         self.age = age
5 
6 obj = foo('haha',22) 
7 print(obj.name)  #通过“对象.属性名”调用被封装的内容
 1 class foo:
 2     def __init__(self,name,age):
 3         self.name = name
 4         self.age = age
 5 
 6     def detail(self):
 7         print(self.name)   #通过“self.name”调用被封装的内容
 8         print(self.age)
 9 
10 obj = foo('haha',22) 
11 obj.detail()

2.继承

继承可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。

对于面向对象的继承来说,其实就是将多个类共有的方法提取到父类中,子类仅需继承父类而不必一一实现每个方法。

通过继承创建的新类称为“子类”或“派生类”,被继承的类称为“基类”、“父类”或“超类”,继承的过程,就是从一般到特殊的过程。

一个子类可以继承多个基类。但是一般情况下,一个子类只能有一个基类,要实现多重继承,可以通过多级继承来实现。

 1 class SchoolMember(object):  #父类
 2     member_nums = 0
 3     def __init__(self,name,age,sex):
 4         self.name = name
 5         self.age = age
 6         self.sex = sex
 7         self.enroll()
 8 
 9     def enroll(self):
10         SchoolMember.member_nums +=1
11         print("the [%s] SchoolMember [%s] is enrolled!" %(self.member_nums,self.name))
12 
13     def tell(self):
14         print("hello my name is %s" %self.name)
15 
16 class Teacher(SchoolMember):  #子类,继承父类
17     def __init__(self,name,age,sex,course,salary):
18         super(Teacher,self).__init__(name,age,sex)
19         self.course = course
20         self.salary = salary
21         #SchoolMember.__init__(self,name,age,sex)  旧的写法
22     def teaching(self):
23         print("Teacher [%s] is teaching [%s]" %(self.name,self.course))
24 
25 class Student(SchoolMember):
26     def __init__(self,name,age,sex,course,tuition):
27         super(Student,self).__init__(name,age,sex)  #继承
28         self.course = course
29         self.tuition = tuition
30     def pay_tution(self):
31         print("cao,student [%s] paying tution [%s]" %(self.name,self.tuition))
32 
33 t1 = Teacher("haha",50,"","PY",250)
34 t2 = Teacher("hehe",60,"","PY",741)
35 
36 s1 = Student("nima",24,"","python",1000)
37 s2 = Student("nimei",23,"","python",1200)
38 t1.tell()
39 t2.teaching()
40 s1.tell()
41 s2.pay_tution()
42 
43 #输出结果
44 #the [1] SchoolMember [haha] is enrolled!
45 #the [2] SchoolMember [hehe] is enrolled!
46 #the [3] SchoolMember [nima] is enrolled!
47 #the [4] SchoolMember [nimei] is enrolled!
48 #hello my name is haha
49 #Teacher [hehe] is teaching [PY]
50 #hello my name is nima
51 #cao,student [nimei] paying tution [1200]
继承实例

继承多个类

继承多个类,寻找方法的方式,深度优先和广度优先,Python3.0不管新式类还是经典类都是广度优先

深度优先:当类是经典类时,多继承情况下,会按照深度优先方式查找

广度优先:当类是新式类时,多继承情况下,会按照广度优先方式查找

 1 class A:
 2     n = 'A'
 3     def f2(self):
 4         print("f2 from A")
 5 class B(A): #继承A
 6     n = 'B'
 7     def f1(self):
 8         print("from B")
 9     def f2(self):
10         print("f2 from B")
11 class C(A):
12     n = 'C'
13     def f2(self):
14         print("from C")
15 
16 class D(B,C):  #多继承,先找B,C,A 广度优先
17     '''test class'''
18     def __del__(self):
19         print("deleteing the...")
20 
21 #经典类,深度优先,Python3.0不管新式类还是经典类都是广度优先
22 
23 d = D()
24 d.f1()
25 d.f2()
26 print(d.__doc__) #打印类的介绍
1 from multi_inheritance import D
2 
3 a = D()
4 print(a.__module__)  #打印从哪个文件导入

3.多态

多态性(polymorphisn)是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。多态是为了实现另一个目的——接口重用!多态的作用,就是为了类在继承和派生的时候,保证使用“家谱”中任一类的实例的某一属性时的正确调用。

Pyhon不支持多态并且也用不到多态,多态的概念是应用于Java和C#这一类强类型语言中

 1 class Animal:
 2     def __init__(self, name):    # Constructor of the class
 3         self.name = name
 4     def talk(self):              # Abstract method, defined by convention only
 5         raise NotImplementedError("Subclass must implement abstract method")
 6 
 7 class Cat(Animal):
 8     def talk(self):
 9         return 'Meow!'
10 
11 class Dog(Animal):
12     def talk(self):
13         return 'Woof! Woof!'
14 
15 def animal_talk(obj):  #python不需要指定类型,所以没有多态
16     print(obj.talk())  
17 #==========================================
18 c = Cat("nima")
19 d = Dog("nimei")
20 animal_talk(c)
21 animal_talk(d)

其他类型的语言

1 def animal_talk(万能类型,obj): #必须指定类型Dog或者Cat,使用万能类型为多态,接口重用
2     print(obj.talk())
3 #==========================================
4 c = Cat("nima")
5 d = Dog("nimei")
6 animal_talk(c)
7 animal_talk(d)

四、类的方法与属性

1.类方法

 1 class Animal:
 2     def __init__(self,name):
 3         self.name = name
 4     hobbie = "meat"
 5 
 6     @classmethod #类方法,不能访问实例变量
 7     def talk(self):
 8         print("%s is talking..." % self.name)  #不能访问实例变量name
 9         print("%s is talking..." % self.hobbie)  #类变量可以访问
10 
11 d = Animal("yoyo")
12 d.talk() 

2.静态方法

 1 class Animal:
 2     def __init__(self,name):
 3         self.name = name
 4     hobbie = "meat"
 5 
 6     @staticmethod  #静态方法,不能访问类变量及实例变量
 7     def walk(self):
 8         print(" %s is talking..." % self.hobbie)  #不可以
 9 
10     def walk():
11         print(" is talking..." )  #正确方法
12 
13 d = Animal("yoyo")
14 d.walk()

 

3.属性

1     @property  #把方法变成属性
2     def habit(self):
3         print("%s habit is football" %self.name)
4 d.habit  #调用

私有属性,属性的修改和删除

 1 class Animal:
 2     def __init__(self,name):
 3         self.name = name
 4         self.__num = None  #私有属性    
 5 
 6     @property
 7     def total_players(self):
 8         return self.__num  #私有属性,只能在里面自己用,对外面隐藏
 9 
10     @total_players.setter  #修改属性
11     def total_players(self,num):
12         self.__num = num
13         print("total players:",self.__num)
14     @total_players.deleter  #删除属性
15     def total_players(self):
16         print("total players got deleted.")
17         del self.__num
18 
19 d = Animal("yoyo")
20 print(d.total_players)  #None
21 d.total_players = 3  #赋值
22 print(d.__num) #无法访问私有属性
23 d.__num = 9  #外部修改为9,内部还是3
24 print(d.__num)
25 print("OUT:",d._Animal__num) #特例访问私有变量
26 print(d.total_players) #结果为3
27 del d.total_players  #删除属性

4.类的特殊成员

 

 (1)__doc__:显示类的描述信息

1 class Foo:
2     """ test class """  #类的介绍
3     def func(self):
4         pass
5 print(d.__doc__) #打印类的介绍

(2)__module__:表示当前操作的对象在那个模块

1 from multi_inheritance import D
2 
3 a = D()
4 print(a.__module__)  #打印从哪个文件导入

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

1 class Foo:
2 
3     def __init__(self, name,age):
4         self.name = name
5         self.age = age
6 
7 a = Foo("wu",22)

(4)__del__:析构方法,当对象在内存中被释放时,自动触发执行

1     def __del__(self): 
2         print("deleteing the...") 

(5)__call__:对象后面加括号,触发执行

 1 class Foo:
 2 
 3     def __init__(self):
 4         pass
 5     
 6     def __call__(self, *args, **kwargs):
 7 
 8         print '__call__'
 9 
10 
11 obj = Foo() # 执行 __init__
12 obj()       # 执行 __call__

(6)__dict__:获取类或对象中的所有成员

1  class Foo:
2      def __init__(self):
3          print('__init__')
4          self.n =4
5 print(obj.__dict__)  #以字典的形式显示,可以查看所有变量

6 MyShinyClass = type('MyShinyClass',(),{"test":123}) #一句话定义一个类 7 print(type(MyShinyClass)) #类是由type创建 8 a = MyShinyClass() 9 print(MyShinyClass.test)

五、反射

#反射.py
import sys
class WebServer(object):
    def __init__(self,host,port):
        self.host = host
        self.port = port

    def start(self):
        print("Server is starting...")
    def stop(self):
        print("Server is stopping...")
    def restart(self):
        self.stop()
        self.start()

if __name__ == "__main__":
    server = WebServer('localhost',333)

#传统解决方法
    cmd_dic = {
        'start':server.start,
        'stop':server.stop
    }

    if sys.argv[1] in cmd_dic:
        cmd_dic[sys.argv[1]]()

#输入python 反射.py restart
#输出Server is stopping...
#      Server is starting...

利用反射

import sys
class WebServer(object):
    def __init__(self,host,port):
        self.host = host
        self.port = port

    def start(self):
        print("Server is starting...")
    def stop(self):
        print("Server is stopping...")
    def restart(self):
        self.stop()
        self.start()

def test_run(name):
    print("running...",name)

if __name__ == "__main__":
    server = WebServer('localhost',333)
    #print(sys.argv[1])
    if hasattr(server,sys.argv[1]):  #判断
        func = getattr(server,sys.argv[1])  #获取server.start 内存地址
        func()  #server.start()

    setattr(server,'run',test_run)  #设置,把test_run添加到实例
    server.run("alex")

    delattr(server,'host')  #删除host
    delattr(WebServer,'start')  #删除start
    print(server.host)
    print(server.restart())
原文地址:https://www.cnblogs.com/yoyovip/p/5702870.html