Python 面向对象

Stella981
• 阅读 446

面向对象

面向对象

  • 与面向过程对比:二狗子准备结婚,需要盖房子

    • 面向过程:数学逻辑的映射,学会做个好员工

    • 面向对象:生活逻辑的映射,学会做个好领导

  • 生活实例

    • 类: 人 手机 电脑

    • 对象: 习大大、黄友 杰哥的T2手机、路飞的iPhone X 杰哥的mac、李森的华硕

  • 官方定义:

    • 类:具有相同特征(属性和行为)事物的抽象

    • 对象:某个类的具象

  • 编程语言:

    • 类:是一种自定义的数据类型

    • 对象:某个类型的变量

类的语法

  • 定义类:

    class 类名: 内容
    
  • 示例:定义一个人的类

    # 定义类
    class Person:
        # 行为的体现,通过方法
    ​
        # 吃饭
        def eat(self):
            print('红烧鸡腿我喜欢吃')
    ​
        # 打篮球
        def play(self):
            print('俺喜欢打篮球')
    
  • 声明对象

bryant = Person()

  • 调用方法

bryant.eat()

bryant.play()

  • 设置属性:是动态添加的

bryant.name = '科比.布莱恩特'

  • 获取属性

print(bryant.name)

​- 语法​ - 定义类需要使用关键字:class - 类名:原则上只要符合标识符的命名规范即可,但是我们通常使用大驼峰风格(每个单词首字母大写)命名 - 不要忘记类名后面的冒号':' - 类的内容要进行缩进 - 行为:通过函数体现,与外面定义函数的方式相似,第一个参数默认是self - 属性:通过变量体现,属性是动态添加的,因此在定义时可以不体现 - 成员访问:   - 成员属性:对象.属性名   - 成员方法:对象.方法名()​- self​ - 示例:​ ```python

class Person:
      def run(self):
          # self表示当前对象:谁调用该方法就代表谁
          print('{}每天以2m/s的速度锻炼5km'.format(self.name))
​
      def introduce(self):
          # self这个名字可以是任意的,但是通过都是要这个
          
          # 既可以访问成员属性
          print('我叫{}'.format(self.name))
          # 也可以调用成员方法
          self.run()
​
  mugai = Person()
  mugai.name = '木盖'
​
  # print(mugai)
  mugai.run()
​
  curry = Person()
  curry.name = '斯蒂芬.库里'
  curry.run()
  # 调用方法是第一个参数self不需要
  curry.introduce()
  • 说明:

    • 每个成员方法都有这么一个参数,调用的时候不需要传递

    • 名字可以不是self,只不过通常我们都是要self而已

    • self表示当前对象,谁调用该方法就表示谁,哪个对象调用就代表哪个对象

    • 通过self可以访问成员属性,也可以调用成员方法

  • __ str __方法

    • 示例:

      class Person: # 使用print函数打印对象时,默认打印对象所属类型及对象地址 # 该函数要求返回一个字符串,当对象作为print参数打印时会打印该字符串 def str(self): # 要求返回一个字符串 return '我叫{},今年{}'.format(self.name, self.age) xiaoming = Person()xiaoming.name = '小明'xiaoming.age = 18

      print(xiaoming)

- 练习:

- 自定义一个狗类,完成属性的动态添加,方法的调用
- 属性:名字、年龄、颜色
- 方法:跑、吃、游泳、叫

  • 构造方法

    • 作用:用于对象创建后初始化相关的属性

    • 示例:

      class Cat: def init(self, name, age): # 创建对象后进行初始化操作,系统会自动调用 # 也叫构造方法 print('init') self.name = name self.age = age self.color = '白色'

      创建对象时的参数要与构造方法一致

      tom = Cat('Tom', 1) print(tom)

  • 析构方法

    • 作用:当对象即将销毁时,系统会自动调用

    • 示例:

      class Pig: def del(self): # 当对象释放时系统会自动调用,如果使用del删除对象,则立即释放调用该方法 # 一般在此处做:断开连接、关闭文件、释放资源等 print('大师兄,我不行了') ​ bajie = Pig() ​

      若删除对象,则会立即调用 析构方法

      del bajie ​ print('一路走好')

  • 示例:小明手里有两张牌,左手♥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=None): 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)) print('左手:{}'.format(self.left_hand.poker)) 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()

  • 练习:

  • 设计一个数学类,方法有加减乘除,并能展示结果

类属性

  • 说明:定义类时,写在类中,但是方法外的属性,通过放在类的开头位置

  • 示例:

    class Person:
        # 定义类属性
        nation = '中国'
    ​
        def __init__(self, name):
            self.name = name
            self.nation = 'china'
    ​
    # 通过类名访问类属性
    print(Person.nation)
    ​
    p = Person('xiaoming')
    # 通过对象也可访问类属性,但是不建议
    # 当对象有同名的成员属性时,使用的就是成员属性
    print(p.nation)
    ​
    # 也可以动态添加
    Person.hello = 'hello'
    print(Person.hello)
    ​
    # 特殊的类属性
    # 表示的类名字符串
    print(Person.__name__)
    ​
    # 表示父类构成的元组
    print(Person.__bases__)
    ​
    # 存储类相关的信息
    print(Person.__dict__)
    

类方法

  • 说明:

    • 定义时使用装饰器:classmethod

    • 通过类名进行调用

  • 作用:

    • 可以创建对象或者简洁的创建对象

    • 对外提供简单易用的接口

  • 示例1:语法:

    class Person:
        def eat(self):
            print('麻辣是我的最爱')
    ​
        # 使用装饰器 classmethod 修饰的方法 就是类方法
        @classmethod
        def test(cls):
            print('类方法 test')
            # cls 表示当前类
            print(cls)
    ​
        @classmethod
        def create(cls):
            p = cls()
            # 进行特定的初始化设置
            p.age = 1
            return p
    ​
    Person.test()
    # print(Person)
    # 可以创建或者简洁的创建对象
    p = Person.create()
    print(p)
    
  • 示例2:设计一个数字类,用于两个属性,能够进行加减乘除运算,要求:计算两个数的平方和

    class Number:
        def __init__(self, num1, num2):
            self.num1 = num1
            self.num2 = num2
    ​
        def add(self):
            return self.num1 + self.num2
    ​
        def sub(self):
            return self.num1 - self.num2
    ​
        def mul(self):
            return self.num1 * self.num2
    ​
        def div(self):
            if self.num2 == 0:
                return None
            return self.num1 / self.num2
        
        @classmethod
        def pingfanghe(cls, num1, num2):
          # 第一个数
          n1 = Number(num1, num1)
          # 求平方
          n12 = n1.mul()
    ​
          # 第二个数
          n2 = Number(num2, num2)
          # 求平方
          n22 = n2.mul()
    ​
          # 第三个数
          n3 = Number(n12, n22)
    ​
          return n3.add()
    ​
    he = Number.pingfanghe(3, 4)
    print(he)
    

静态方法

  • 说明:

    • 使用装饰器:staticmethod进行修饰

    • 定义的方法没有第一个表示当前类参数

  • 示例:

    class Person:
          @staticmethod
          def test():
              print('static method test')
    ​
          @staticmethod
          def create():
              # 也可以创建对象
              p = Person()
              return p
    ​
      Person.test()
    ​
      p = Person.create()
    

    与类方法对比:

    1. 除了装饰器不同,其他基本一样,做与对象创建无关的任务时可以使用静态方法

    2. 所有静态方法能够完成的功能都是使用类方法完成

多态特性

  • 定义:不同的对象,调用相同的方法有不同的响应称为多态

  • 体现:多态性,不同对象接收相同的消息会有不同的响应。

  • 示例:

    class Animal:
        def run(self):
            pass
    ​
    class Dog(Animal):
        def run(self):
          print('狗奔跑的时候一般是s型')
        
    class Cat(Animal):
        def run(self):
          print('猫平时走猫步,偶尔会突然加速')
        
        
    # 参数必须有run方法
    def func(obj):
        obj.run()
        
    func(Dog())
    func(Cat())
    

属性函数

  • 说明:就是将方法当做属性一样

  • 作用:保护特定属性,处理特定属性

  • 示例:

    class User:
          def __init__(self, username, password):
              self.username = username
              self.__password = password
    ​
          # 使用property修饰的方法,可以当做属性访问
          # 可以保护特定的属性
          @property
          def password(self):
              print('有人想直接获取密码')
              # return self.__password
              return '哈哈,想偷看,没门'
    ​
          # 当设置password属性时,会自动调用该方法
          @password.setter
          def password(self, password):
              print('注意了,有人想修改密码', password)
              # 可以对密码进行特定处理,然后保存
              self.__password = 'xxx'+ password+'yyy'
    
    u = User('xiaoming', '123456')
    print(u.username)
    # 很多时候直接访问密码是不需要的,也是不安全的
    # 直接访问password属性,自动回调用使用property修饰后的password方法
    print(u.password)
    u.password = '654321'
    
    ​
    

    内置方法​- 说明:​ - 当将对象当做函数一样调用时,系统会自动触发 __ call __ 方法 - 若想支持这样的操作,系统在类中提供 __ call __ 方法​- 示例:​ ```python

    class Person: # 当对象当做函数一样调用时,系统会自动触发该方法 def call(self, *args, **kwargs): # 如:计算和 return sum(args) ​ p = Person()

    将对象当做函数使用,需要提供 call 方法

    ret = p(1,2,3, name='xiaoming') print(ret)

函数判断

  • 问题:如何判断一个对象是否可以像函数一样调用

  • 示例:

    class A:
        def __call__(self, *args, **kwargs):
            print('xx')
    ​
    def test():
        pass
    ​
    # 不能使用isinstance方法判断一个对象是否是函数
    # isinstance(test, function)
    ​
    # 打印时仍然是function类型
    # print(type(test))
    ​
    # 判断一个对象是否可以像函数一样调用
    print(callable(test))
    a = A()
    print(callable(a))
    ​
    # 判断对象是否拥有 call属性
    print(hasattr(test, 'call'))
    print(hasattr(a, 'call'))
    ​
    # 判断是否是函数
    from inspect import isfunction
    print(isfunction(test))
    print(isfunction(a))
    

数据持久化存储

  • 方式:普通文件、数据库、序列化

  • 示例:

    import pickle

    class Person: def init(self, name, age): self.name = name self.age = age

    存储:对象 => 文件

    xiaoming = Person('小明', 18)

    fp = open('text.txt', 'wb')

    pickle.dump(xiaoming, fp)

    print('对象数据已存储完毕')

    读取:文件 => 对象

    fp = open('text.txt', 'rb') xiaoming = pickle.load(fp)

    print(xiaoming.name) print(xiaoming.age)

    fp.close()

- 说明:可以将对象保存到文件中,以便在合适的时候从文件中加载数据

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
2年前
java常用类(2)
三、时间处理相关类Date类:计算机世界把1970年1月1号定为基准时间,每个度量单位是毫秒(1秒的千分之一),用long类型的变量表示时间。Date分配Date对象并初始化对象,以表示自从标准基准时间(称为“历元”(epoch),即1970年1月1日08:00:00GMT)以来的指定毫秒数。示例:packagecn.tanjian
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Stella981 Stella981
2年前
Python3:sqlalchemy对mysql数据库操作,非sql语句
Python3:sqlalchemy对mysql数据库操作,非sql语句python3authorlizmdatetime2018020110:00:00coding:utf8'''
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Stella981 Stella981
2年前
JS 对象数组Array 根据对象object key的值排序sort,很风骚哦
有个js对象数组varary\{id:1,name:"b"},{id:2,name:"b"}\需求是根据name或者id的值来排序,这里有个风骚的函数函数定义:function keysrt(key,desc) {  return function(a,b){    return desc ? ~~(ak
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这