代码改变世界

Python 面向对象补充

2018-06-19 09:22  钱先生  阅读(170)  评论(0编辑  收藏  举报

什么是面向对象编程

  • 类 + 对象
    • class 类:
      • def 函数1():
        • pass
      • def 函数2():
        • pass
    • obj是对象, 实例化的过程
      • obj = 类()
      • obj.函数1()

 

例1 , 某些方法被反复调用. 如: 登录服务器并上传文件. 

函数式编程:

def upload():
    # 连接服务器
    # 上传文件
    # 关闭

def cmd():
    # 连接服务器
    # 执行命令
    # 关闭

def upload_cmd():
    # 连接服务器
    # 上传文件
    # 执行命令
    # 关闭

 

面向对象编程:

class SSH:
    def __init__(self, host, port, pwd, username):
        self.host=
        ...

    def connection(self):
        # 去创建连接
        self.conn = 和服务器创建的连接对象()

    def close(self):
        # 关闭
        self.conn.关闭

    def upload(self):
        self.conn 使用连接上传文件

    def cmd(self):
        self.conn 使用连接执行命令

obj = SSH(.......)
obj.connection()
obj.upload()
obj.close()


obj = SSH(.......)
obj.connection()
obj.cmd()
obj.cmd()
obj.upload()
obj.cmd()
obj.close()

注:  若需要改变服务器连接, 函数式编程所有函数都需要修改;  而面向对象编程只需要更改connection()方法即可. 

 

例2: 多个函数需要传入多个共同的参数. 如:多个函数需要的参数有相同部分也有不同部分(类似java中方法重载)

函数式编程:

def f1(host, port, pwd, arg)
    pass

def f2(host, port, pwd, arg, arg2)
    pass

def f3(host, port, pwd, arg, arg2, arg3)
    pass


f1(1,1,1,2)
f2(1,1,1,2,2)
f3(1,1,1,2,2,3)

 

面向对象编程:

class Foo:
    def __init__(self, host, port, pwd):
        self.host = host
        self.port = port
        self.pwd = pwd

    def f1(arg):
        pass
    
    def f2(arg,arg2):
        pass

    def f3(arg, arg2, arg3):
        pass


obj = Foo(1,1,1)
obj.f1(1)
obj.f2(2,2)
obj.f3(3,3,3)

 

 

什么时候适用面向对象

  • 多个步骤在不同函数中反复调用.可以将各个步骤抽取出来写在一个类中,每个步骤写一个方法,这样调用时就可以任意组合.
  • 根据一个模版创建某些东西(也是加以某些限制)
  • 多个函数传入多个共同的参数时,可以写在一个类中,共同的参数抽取出来写在构造函数中.

 

class Foo:
    # 静态字段 (公有属性), 适合每一个对象都有的共同的值时, 把这个值抽取出来作为静态字段.
    country = "中国"

    def __init__(self, name, count):
        # 普通字段(普通属性)
        self.name = name
        self.count = count

    def bar(self):
        pass


obj1 = Foo('河南', 100000)
obj1.bar()

 

封装:

  • 类中封装: 字段, 方法
  • 对象中封装: 普通字段的值
  • class F1:
        def __init__(self, n):
            self.n = n
            print('F1')
    
    
    class F2:
        def __init__(self, arg1):
            self.a = arg1
            print('F2')
    
    
    class F3:
        def __init__(self, arg2):
            self.b = arg2
            print('F3')
    
    
    o1 = F1('alex')
    o2 = F2(o1)
    o3 = F3(o2)
    
    print(o3.b.a.n)  # 输出alex
    封装

     

继承:

  • self代指当前对象
  • class F1:
        def __init__(self):
            print('F1')
    
        def a1(self):
            print('F1a1')
    
        def a2(self):
            print('F1a2')
    
    
    class F2(F1):
        def __init__(self):
            print('F2')
    
        def a1(self):
            self.a2()
            print('F2a1')
    
        def a2(self):
            print('F2a2')
    
    class F3(F2):
        def __init__(self):
            print('F3')
    
        # def a1(self):
        #     print('F3a1')
    
        def a2(self):
            print('F3a2')
    
    
    obj = F3()
    obj.a1()  # 先返回F3a2然后返回F2a1
    继承

     

字段

  • 普通字段(保存在对象中)
  • 静态字段(保存在类中)

 

方法

  • 普通方法(保存在类中, 调用者对象)
  • 静态方法(可以有任意个参数)
    • 在方法上添加注释 @staticmethod
    • 不需要创建对象,可以直接类名.方法()调用
    • class F1:
          @staticmethod  # 标识某方法为静态方法
          def a1():
              print('alex')
      
      F1.a1()  # 调用方法

 

 

 

组合

  • 把一个类实例化, 实例化对象作为参数传入另一个类.
  • #!/usr/bin/python
    # -*- coding: utf-8 -*-
    
    
    """
    命名规范:
    1. 类名每个单词都要首字母大写
    2. 类名下面要写注释
    """
    
    
    class SchoolMember(object):
        """
        学校成员基类
        """
        member = 0
    
        def __init__(self, name, age, sex):
            self.name = name
            self.age = age
            self.sex = sex
            self.enroll()
    
        def enroll(self):
            """
            注册
            :return:
            """
            print("just enrolled a new school memeber [%s]" % self.name)
            # self.member += 1  # 每新注册一个, 成员数加1. 这样写只是当前子类成员数加1;要想父类SchoolMember总成员数加1, 需得加到全局变量里.
            SchoolMember.member += 1
    
        def tell(self):
            print('------------%s info ----------' % self.name)
            for k, v in self.__dict__.items():  # __dict__方法可以打印出类的所有变量
                print("\t", k, v)
            print("end".center(33, "-"))
    
        def __del__(self):
            print("开除了[%s]" % self.name)
            SchoolMember.member -= 1
    
    
    class School(object):
        """
        假装是另一个社团团员类(以便Teacher和Student能继承;否则School是个组织, Teacher/Student是不能继承的)
        """
        def open_branch(self, addr):
            print("opening new branch in ", addr)
    
    
    
    class Student(SchoolMember):
        def __init__(self,name, age, sex, course, tuition, school_obj):
            SchoolMember.__init__(self, name, age, sex)
            self.school = school_obj  # 组合. 相当于把School实例化, 再把实例化对象传入Student作为一个参数,这样就可以调用School的变量和方法
            self.course = course
            self.tuition = tuition  # fee
            # self.enroll()  # enroll()方法在每个子类里都需要, 可以直接写在父类里
            self.amount = 0
    
        def pay_tuition(self, amount):
            print("student [%s] has just paid [%s]" %(self.name, amount))
            self.amount += amount
    组合