437°

11-面向对象(01)

面向对象

面向对象

  • 与面向过程对比:
    • 面向过程:数学逻辑的映射,学会做个好员工
    • 面向对象:生活逻辑的映射,学会做个好领导
  • 生活实例:
    • 类: 人 手机 电脑
      • 对象: 我的手机、女朋友的手机 你的那部T400、老板桌上的电脑
  • 官方定义:
    • 类:具有相同特征(属性和行为)的事物的抽象
    • 对象:某个类的具象
  • 编程语言:
    • 类:是一种自定义的数据类型
    • 对象:某个类类型的变量

面向对象语法

  • 类的定义:

    class 类名:
        内容

     

  • 语法说明:

    • 定义类需要使用关键字class
    • 类名:原则上只要符合标识符命名规范即可,但是通过我们都使用大驼峰(每个单词首字母大写)风格命名
      • 如:UserName
    • 类名后面的':'不要忘记
    • 类的内容要进行整体缩进
    • 行为:通过方法体现,在类中定义相关的函数即可(第一个参数通常是self)
    • 属性:通过变量体现,在需要时动态添加,很多时候定义类时没有体现
    • 成员访问:
      • 属性:对象.属性名
      • 方法:对象.方法名()
  • 示例:

    # 定义类
    class Person:
        # 行为通过方法体现
    
        # 吃饭
        def eat(self):
            print('红烧排骨我喜欢吃')
    
        # 睡觉
        def sleep(self):
            print('睡觉也是一种生活态度')
            
    # 定义对象
    liang = Person()
    # 调用方法
    liang.eat()
    liang.sleep()
    # 属性时动态添加的
    liang.name = '上官'
    # 获取属性
    print(liang.name)

     

  • self使用

    class Person:
        def run(self):
            # self表示当前对象:谁调用该方法就表示谁
            print('{}每天以2m/s的速度慢跑5km'.format(self.name))
    
        def introduce(self):
            # 不但可以访问成员属性
            print('我叫{}'.format(self.name))
            # 还可以调用成员方法
            self.run()
            
    fei = Person()
    fei.name = '欧阳'
    fei.run()
    fei.introduce()
    
    long = Person()
    long.name = '诸葛'
    long.introduce() 

     

    • 说明:
    1.类中的每个成员方法都有一个self参数,调用的时候不需要传递该参数
    2.该参数的名字可以不是self,只不过通常我们都使用这个
    3.self表示当前对象,对调用该方法self就代表谁,哪个对象调用就表示哪个对象
    4.通过self可以访问成员属性,也可以调用成员方法 

     

  • __str__方法

    class Person:
        # 使用print方法打印对象,默认打印 类名 + 地址
        # 若想打印特定内容,重写该方法即可,要求返回一个字符串
        def __str__(self):
            return '我叫{},今年{}'.format(self.name, self.age)
        
    james = Person()
    james.name = '勒布朗.詹姆斯'
    james.age = 33
    print(james)  

     

  • 练习:

    • 自定义一个狗类,添加如下属性和方法:
      • 属性:名字、年龄、颜色
      • 方法:跑、吃、游泳、吠、描述
  • 构造方法:创建对象后,初始化属性时,系统会自动调用该方法

    class Cat:
        def __str__(self):
            return 'name:{},age:{},color:{}'.format(self.name, self.age, self.color)
    
        # 构造方法:创建对象后,初始化系统就会自动调用该方法
        def __init__(self, name, age, color):
            print('__init__')
            self.name = name
            self.age = age
            self.color = color
            
    # 这种形式比较繁琐
    # tom = Cat()
    # tom.name = 'Tom'
    # tom.age = 3
    # tom.color = '蓝色'
    
    # 这种比较简洁
    tom = Cat('Tom', 3, '蓝色')
    print(tom) 

     

  • 析构方法:当对象释放时系统会自动调用,通常用于释放资源

    class Pig:
        # 析构方法:当对象释放时,系统会自动调用
        # 若手动使用del删除,则会立即调用该方法
        # 该方法一般做资源释放处理:数据库连接断开,文件关闭
        def __del__(self):
            print('大师兄,我不行了')
            
    bajie = Pig()
    del bajie
    print('八戒,一路走好!')   

     

  • 经典示例:小明手里有两张牌,左手♥K,右手♠A,小明交换两手的牌后,手里分别是什么?

    • 思路:
      • 先找到对象:左手、右手、♥K、♠A、小明
      • 根据对象抽象出对应的类:人、手、牌
      • 根据需要写出相应的逻辑,很可能反过来完善类的设计
      • 按照题目要求创建相关对象,调用相关方法,实现相关功能
    • 代码:
    # 对象:小明、左手、右手、♥K、♠A
    # 类:人、手、牌
    # 设计相应的类
    
    # 扑克牌
    class Poker:
        def __init__(self, color, number):
            self.color = color
            self.number = number
    
        def __str__(self):
            return '{}{}'.format(self.color, self.number) 
        
    # 创建两张牌
    p1 = Poker('', 'K')
    p2 = Poker('', 'A')
    
    # 手的类
    class Hand:
        def __init__(self, poker):
            self.poker = poker
    
        def hold_poker(self, poker):
            self.poker = poker
     
    # 创建左右两只手
    left_hand = Hand(p1)
    right_hand = Hand(p2)
    
    # 人的类
    class Person:
        def __init__(self, name, left_hand, right_hand):
            self.name = name
            self.left_hand = left_hand
            self.right_hand = right_hand
    
        # 展示手里的牌
        def show(self):
            print('{}张开手'.format(self.name), end=' ')
            print('左手:{}'.format(self.left_hand.poker), end=',')
            print('右手:{}'.format(self.right_hand.poker))
    
        # 交换两手的牌
        def swap(self):
            self.left_hand.poker, self.right_hand.poker = self.right_hand.poker, self.left_hand.poker
            print('{}交换两手的牌'.format(self.name))   
            
    # 创建小明对象
    xiaoming = Person('小明', left_hand, right_hand)
    
    # 展示手里的牌
    xiaoming.show()
    
    # 交换两手的牌
    xiaoming.swap()
    
    #再次展示
    xiaoming.show()

     

  • 练习:设计一个数学类,有两个成员属性,成员方法有加、减、乘、除,展示成员。

常用内置函数

  • 内置函数:在类的内部,特定时机自动触发的函数。

  • 示例:setattr、getattr、delattr

    class Person:
          def __init__(self, name):
              self.name = name
    
          def __str__(self):
              return '姓名:{}'.format(self.name)
    
          def __del__(self):
              print('对象即将销毁')
              
          # 当获取不存在的属性时,会自动触发该方法
          def __getattr__(self, item):
              if item == 'age':
                  return 18
              else:
                  return '你猜'
    
          # 当设置不存在的属性时,会自动触发该方法
          def __setattr__(self, key, value):
              print(key, value)
              self.__dict__[key] = value
    
          # 销毁对象成员属性时,会自动触发该方法
          def __delattr__(self, item):
              print(item, '即将销毁')
            
    xiaoming = Person('小明')
    xiaoming.age = 20
    print(xiaoming.age)
    # 存放对象的所有属性
    # print(xiaoming.__dict__)
    # print(xiaoming)
    del xiaoming.age    

     

  • 将对象当做字典操作,特定时机会自动触发的方法

    class Person:
        # 将对象当做字典操作,设置键值对时会触发该方法
        def __setitem__(self, key, value):
            # print(key, value)
            self.__dict__[key] = value
    
        # 将对象当做字典操作,根据键获取值时会触发该方法
        def __getitem__(self, item):
            # print(item)
            return self.__dict__.get(item)
    
        # 将对象当做字典操作,删除指定的键值对时自动触发
        def __delitem__(self, key):
            del self.__dict__[key]
            
    xiaoming = Person()
    
    xiaoming['name'] = '小明'
    print(xiaoming.__dict__)
    
    print(xiaoming['name'])
    
    del xiaoming['name'] 

     

  • 将对象当做函数调用时,会自动触发下面方法

    class Person:
        # 将对象当做函数调用时,会自动触发该方法
        def __call__(self, *args, **kwargs):
            # print('__call__')
            return sum(args)
        
    xiaoming = Person()
    
    # 这样操作,需要提供call方法
    ret = xiaoming(1, 2, 3, name='小明')
    print(ret)  

     

  • 函数判断

    class A:
        def __call__(self, *args, **kwargs):
            pass
    
    def test():
        pass
    
    a = A()
    
    # 判断是否可调用
    print(callable(test))
    print(callable(a))
    
    # 判断是否拥有'__call__'属性
    print(hasattr(test, '__call__'))
    print(hasattr(a, '__call__'))
    
    # 判断是否是函数
    from inspect import isfunction
    print(isfunction(test))
    print(isfunction(a))

原文链接:https://www.cnblogs.com/swjblog/p/9677631.html

全部评论: 0

    我有话说: