Python 面向对象

面向对象

面向对象

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

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

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

  • 生活实例

    • 类: 人 手机 电脑

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

  • 官方定义:

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

    • 对象:某个类的具象

  • 编程语言:

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

    • 对象:某个类型的变量

类的语法

  • 定义类:

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

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

bryant = Person()

  • 调用方法

bryant.eat()

bryant.play()

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

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

  • 获取属性

print(bryant.name)

1- 语法​ - 定义类需要使用关键字:class - 类名:原则上只要符合标识符的命名规范即可,但是我们通常使用大驼峰风格(每个单词首字母大写)命名 - 不要忘记类名后面的冒号':' - 类的内容要进行缩进 - 行为:通过函数体现,与外面定义函数的方式相似,第一个参数默认是self - 属性:通过变量体现,属性是动态添加的,因此在定义时可以不体现 - 成员访问:   - 成员属性:对象.属性名   - 成员方法:对象.方法名()- self​ - 示例:​ ```python 2 3class Person: 4 def run(self): 5 # self表示当前对象:谁调用该方法就代表谁 6 print('{}每天以2m/s的速度锻炼5km'.format(self.name)) 78 def introduce(self): 9 # self这个名字可以是任意的,但是通过都是要这个 10 11 # 既可以访问成员属性 12 print('我叫{}'.format(self.name)) 13 # 也可以调用成员方法 14 self.run() 1516 mugai = Person() 17 mugai.name = '木盖' 1819 # print(mugai) 20 mugai.run() 2122 curry = Person() 23 curry.name = '斯蒂芬.库里' 24 curry.run() 25 # 调用方法是第一个参数self不需要 26 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()

  • 练习:

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

类属性

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

  • 示例:

    1class Person: 2 # 定义类属性 3 nation = '中国' 45 def __init__(self, name): 6 self.name = name 7 self.nation = 'china' 89# 通过类名访问类属性 10print(Person.nation) 1112p = Person('xiaoming') 13# 通过对象也可访问类属性,但是不建议 14# 当对象有同名的成员属性时,使用的就是成员属性 15print(p.nation) 1617# 也可以动态添加 18Person.hello = 'hello' 19print(Person.hello) 2021# 特殊的类属性 22# 表示的类名字符串 23print(Person.__name__) 2425# 表示父类构成的元组 26print(Person.__bases__) 2728# 存储类相关的信息 29print(Person.__dict__)

类方法

  • 说明:

    • 定义时使用装饰器:classmethod

    • 通过类名进行调用

  • 作用:

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

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

  • 示例1:语法:

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

    1class Number: 2 def __init__(self, num1, num2): 3 self.num1 = num1 4 self.num2 = num2 56 def add(self): 7 return self.num1 + self.num2 89 def sub(self): 10 return self.num1 - self.num2 1112 def mul(self): 13 return self.num1 * self.num2 1415 def div(self): 16 if self.num2 == 0: 17 return None 18 return self.num1 / self.num2 19 20 @classmethod 21 def pingfanghe(cls, num1, num2): 22 # 第一个数 23 n1 = Number(num1, num1) 24 # 求平方 25 n12 = n1.mul() 2627 # 第二个数 28 n2 = Number(num2, num2) 29 # 求平方 30 n22 = n2.mul() 3132 # 第三个数 33 n3 = Number(n12, n22) 3435 return n3.add() 3637he = Number.pingfanghe(3, 4) 38print(he)

静态方法

  • 说明:

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

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

  • 示例:

    1class Person: 2 @staticmethod 3 def test(): 4 print('static method test') 56 @staticmethod 7 def create(): 8 # 也可以创建对象 9 p = Person() 10 return p 1112 Person.test() 1314 p = Person.create()

    与类方法对比:

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

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

多态特性

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

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

  • 示例:

    1class Animal: 2 def run(self): 3 pass 45class Dog(Animal): 6 def run(self): 7 print('狗奔跑的时候一般是s型') 8 9class Cat(Animal): 10 def run(self): 11 print('猫平时走猫步,偶尔会突然加速') 12 13 14# 参数必须有run方法 15def func(obj): 16 obj.run() 17 18func(Dog()) 19func(Cat())

属性函数

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

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

  • 示例:

    1class User: 2 def __init__(self, username, password): 3 self.username = username 4 self.__password = password 56 # 使用property修饰的方法,可以当做属性访问 7 # 可以保护特定的属性 8 @property 9 def password(self): 10 print('有人想直接获取密码') 11 # return self.__password 12 return '哈哈,想偷看,没门' 1314 # 当设置password属性时,会自动调用该方法 15 @password.setter 16 def password(self, password): 17 print('注意了,有人想修改密码', password) 18 # 可以对密码进行特定处理,然后保存 19 self.__password = 'xxx'+ password+'yyy' 20 21u = User('xiaoming', '123456') 22print(u.username) 23# 很多时候直接访问密码是不需要的,也是不安全的 24# 直接访问password属性,自动回调用使用property修饰后的password方法 25print(u.password) 26u.password = '654321' 27 28

    内置方法​- 说明:​ - 当将对象当做函数一样调用时,系统会自动触发 __ 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)

函数判断

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

  • 示例:

    1class A: 2 def __call__(self, *args, **kwargs): 3 print('xx') 45def test(): 6 pass 78# 不能使用isinstance方法判断一个对象是否是函数 9# isinstance(test, function) 1011# 打印时仍然是function类型 12# print(type(test)) 1314# 判断一个对象是否可以像函数一样调用 15print(callable(test)) 16a = A() 17print(callable(a)) 1819# 判断对象是否拥有 call属性 20print(hasattr(test, 'call')) 21print(hasattr(a, 'call')) 2223# 判断是否是函数 24from inspect import isfunction 25print(isfunction(test)) 26print(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()

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

点赞
收藏

评论区

加载中...

相关推荐

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

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

java常用类(2)

三、时间处理相关类Date类:计算机世界把1970年1月1号定为基准时间,每个度量单位是毫秒(1秒的千分之一),用long类型的变量表示时间。Date分配Date对象并初始化对象,以表示自从标准基准时间(称为“历元”(epoch),即1970年1月1日08:00:00GMT)以来的指定毫秒数。示例:packagecn.tanjian