本篇博客承接自Python 面向对象(上)

四. 继承,实现,依赖,关联,聚合,组合

Python面向对象--继承,实现,依赖,关联,聚合,组合

五. 特殊成员

Python面向对象--类的特殊成员

六. issubclass,type,isinstence各自的用法和区别

1. issubclass

语法: issubclass(class1, class2)
参数: class1 和 class2 都是 类
返回值: 返回 True 或 False -- 当class1是class2的家族成员时, 返回True, 否则返回False.

举例说明:

  1. class Animal(object): pass
  2. class Cat(Animal): pass
  3. class BoSiCat(Cat): pass
  4.  
  5. a = Animal()
  6. c = Cat()
  7. bsc = BoSiCat()
  8.  
  9. # print(issubclass(c, Animal))
  10. # 报错: issubclass() arg 1 must be a class
  11. # print(issubclass(Cat, a))
  12. # 报错: issubclass() arg 2 must be a class or tuple of classes
  13.  
  14. print(issubclass(BoSiCat, Cat))
  15. # 输出结果: True
  16. print(issubclass(BoSiCat, Animal))
  17. # 输出结果: True

需要强调的是, issubclass()中的两个参数都是类!

2. type

语法: type(obj)
参数: obj表示一个对象
返回值: 返回创建这个对象的类(也即是对象obj的数据类型)

举例说明:

  1. class Animal(object): pass
  2. class Cat(Animal): pass
  3. class BoSiCat(Cat): pass
  4.  
  5. a = Animal()
  6. c = Cat()
  7. bsc = BoSiCat()
  8.  
  9. print(type(a)) # 精准地判断出创建对象a的类是什么, 给出对象a的数据类型
  10. # <class '__main__.Animal'>
  11. print(type(c))
  12. # <class '__main__.Cat'>

3. isinstence

语法: isinstance(obj, classinfo)

参数:
obj -- 实例对象
classinfo -- 可以是直接或间接类名、基本类型或者由它们组成的元组

返回值: 返回True或False -- 如果对象obj的类型与参数二classinfo的类型相同则返回 True,否则返回 False

举例说明:

  1. class Animal(object): pass
  2. class Cat(Animal): pass
  3. class BoSiCat(Cat): pass
  4.  
  5. a = Animal() # 实例化
  6. c = Cat()
  7. bsc = BoSiCat()
  8.  
  9. # print(isinstance(c, a))
  10. # 报错: isinstance() arg 2 must be a type or tuple of types
  11.  
  12. print(isinstance(c, Animal)) # 判断对象c是否是类Animal
  13. # 输出结果: True
  14. print(isinstance(Cat, Animal)) # 判断类Cat是否是类Animal
  15. # 输出结果: False
  16. print(isinstance(Cat, type)) # 判断类Cat是否是类type
  17. # 输出结果: True

根据上面的例子可以总结出:
(1) isinstance()中的第一个参数必须是实例对象, 第二个参数必须是类名或由类名组成的元组.
(2) 在上面的示例中, 注意到 print(isinstance(Cat, type)) 的执行结果是 True. 事实上, 如果把类也当作一个对象来看, 那么"类"这个对象是"type"类型的, 即"类"是"type"的家族成员.

七. 面向对象中方法与函数的辨别

在类外部: 都是函数

在类内部:
(1)属性 -- 无论谁访问, 属性既不是函数也不是方法
(2)实例方法: 对象访问是方法, 类名访问是函数
(3)静态方法: 无论谁访问, 静态方法都是函数
(4)类方法: 无论谁访问, 类方法都是方法

1. 在类的外部

  1. def func():
  2. print("我是函数func")
  3.  
  4. print(func)
  5. # 执行结果: <function func at 0x00000188BC263E18>

得出结论:

在类外面定义的函数一定是函数

2. 在类的内部

  1. class Foo:
  2.  
  3. def instance_method(self):
  4. print("这里是实例方法")
  5. return "这里是实例方法的返回值"
  6.  
  7. @staticmethod
  8. def static_method():
  9. pass
  10.  
  11. @classmethod
  12. def class_method(cls):
  13. pass
  14.  
  15. @property
  16. def age(self):
  17. return 10

举例说明

(1)属性

  1. class Foo:
  2. @property
  3. def age(self):
  4. return 10
  5.  
  6. # 引入两个模块
  7. from types import FunctionType, MethodType
  8.  
  9. # 定义一个函数,判断该参数是函数还是方法
  10. def function_method_judge(arg):
  11. print(isinstance(arg, FunctionType))
  12. print(isinstance(arg, MethodType))
  13.  
  14. # 调用函数
  15. function_method_judge(Foo().age)
  16. print(Foo().age)

  17. # 执行结果:
  18. # False
  19. # False
  20. #

得出结论:
在@property的声明下, 我们定义的代码有着方法的表现形式(例如,他是有返回值的),但它既不是函数也不是方法.

(2)实例方法

a.对象去访问:

  1. # 定义一个实例方法
  2. class Foo:
  3. def instance_method(self):
  4. print("这里是实例方法")
  5. return "这里是实例方法的返回值"
  6.  
  7. # 实例化
  8. f = Foo()
  9.  
  10. # 对象访问实例方法名
  11. print(f.instance_method)

以上代码的执行结果是:
<bound method Foo.instance_method of <__main__.Foo object at 0x0000017D7D11AA90>>

得出结论:
对象访问实例方法 --> "实例方法"是"方法"

b.类名去访问:

  1. # 定义一个实例方法
  2. class Foo:
  3. def instance_method(self):
  4. print("这里是实例方法")
  5. return "这里是实例方法的返回值"
  6.  
  7. # 类名访问实例方法
  8. print(Foo.instance_method)

以上代码的执行结果是:
<function Foo.instance_method at 0x000002738C22B9D8>

得出结论:
类名访问实例方法 --> "实例方法"是"函数"

(3)静态方法

  1. # 定义一个静态方法
  2. class Foo:
  3. @staticmethod
  4. def static_method():
  5. pass
  6.  
  7. # 实例化
  8. f = Foo()
  9.  
  10. # 对象访问静态方法
  11. print(f.static_method)
  12. # 类名访问静态方法
  13. print(Foo.static_method)

以上代码的执行结果分别是:
<function Foo.static_method at 0x0000018E170BB9D8>
<function Foo.static_method at 0x0000018E170BB9D8>

得出结论:
无论是谁去访问静态方法, 静态方法都是函数

(4)类方法

  1. class Foo:
  2. @classmethod
  3. def class_method(cls):
  4. pass
  5.  
  6. # 实例化
  7. f = Foo()
  8.  
  9. # 对象访问类方法
  10. print(f.class_method)
  11. # 类名访问类方法
  12. print(Foo.class_method)

以上代码的执行结果分别是:
<bound method Foo.class_method of <class '__main__.Foo'>>
<bound method Foo.class_method of <class '__main__.Foo'>>

得出结论:
无论是谁去访问类方法, 类方法都是方法

八. 反射

反射: 利用字符串的形式去对象(模块)中操作(查找/获取/删除/添加)成员,一种基于字符串的事件驱动.

1. hasattr

描述: hasattr()函数用于判断对象是否包含对应的属性.

语法: hasattr(object, name)

参数:
object -- 对象
name -- 字符串类型的属性名字(强调: name是属性名)

返回值: 如果对象有名字叫name的属性, 返回True, 否则返回False.

举例说明:

  1. # 创建类
  2. class Person(object):
  3. def __init__(self, name, age, hobby):
  4. self.name = name
  5. self.age = age
  6. self.hobby = hobby
  7.  
  8. # 实例化
  9. p = Person("王菲", 45, "唱歌")
  10.  
  11. # 判断对象p是否有"name", "age", "hobby"属性
  12. print(hasattr(p, "name"))
  13. print(hasattr(p, "age"))
  14. print(hasattr(p, "hobby"))

以上代码执行结果分别是:
True
True
True

得出结论: hasattr()函数用于判断对象是否包含"字符串类型的属性名"所对应的属性, 如果包含返回True, 否则返回False.

2. getattr

描述: getattr() 函数用于返回一个对象属性的值.

语法: getattr(object, name)

参数:
object -- 对象
name -- 字符串类型的属性名字

返回值: 如果对象包含"该属性名对应的属性", 返回属性的值, 否则抛出一个异常: AttributeError.

举例说明:

  1. # 创建类
  2. class Person(object):
  3. def __init__(self, name, age, hobby):
  4. self.name = name
  5. self.age = age
  6. self.hobby = hobby
  7.  
  8. # 实例化
  9. p = Person("王菲", 45, "唱歌")
  10.  
  11. # 从对象p中拿到对应的值
  12. value1 = getattr(p, "name")
  13. value2 = getattr(p, "age")
  14. value3 = getattr(p, "hobby")
  15. print(value1, value2, value3)
  16.  
  17. # 尝试去拿一个p中没有的属性gender
  18. value4 = getattr(p, "gender")

以上代码执行结果是:
王菲 45 唱歌
AttributeError: 'Person' object has no attribute 'gender'

3. setattr

描述: setattr()函数常常与getattr()配合使用, 用于设置属性值, 该属性必须存在.

语法: setattr(object, name, value)

参数:
object -- 对象
name -- 字符串类型的属性名字
value -- 属性值

返回值: 无

举例说明:

  1. # 创建类
  2. class Person(object):
  3. def __init__(self, name, age, hobby):
  4. self.name = name
  5. self.age = age
  6. self.hobby = hobby
  7.  
  8. # 实例化
  9. p = Person("王菲", 45, "唱歌")
  10.  
  11. # 从对象p中拿到对应的值
  12. value1 = getattr(p, "name")
  13. value2 = getattr(p, "age")
  14. value3 = getattr(p, "hobby")
  15. print(value1, value2, value3)
  16.  
  17. # 重新设置对象p的属性值
  18. setattr(p, "name", "刘德华")
  19. setattr(p, "age", 57)
  20. print(p.name, p.age, p.hobby)
  21.  
  22. # 尝试给对象p设置一个他没有的属性
  23. setattr(p, "gender", "男")
  24. print(p.gender)

以上代码执行结果:
王菲 45 唱歌
刘德华 57 唱歌

事实上, 在实际工作中, 当我们需要使用setattr()函数时, 我们必须征得相关领导或同事的同意才能进行操作, 否则, 当有人使用我们的代码时, 会给他们带来很大的困扰与不便. 因此, 对于setattr()函数我们要谨慎使用!

4. delattr

描述: delattr()函数用于删除对象的属性. 补充: delattr(obj, "name")相等于del obj.name

语法: delattr(object, name)

参数:
object -- 对象
name -- 字符串类型的属性名字, 对象必须包含该属性名对应的属性, 否则会抛出异常.

返回值: 无

举例说明:

  1. # 创建类
  2. class Person(object):
  3. def __init__(self, name, age, hobby):
  4. self.name = name
  5. self.age = age
  6. self.hobby = hobby
  7.  
  8. # 实例化
  9. p = Person("王菲", 45, "唱歌")
  10. print(p.name, p.age, p.hobby)
  11. # 执行结果: 王菲 45 唱歌
  12.  
  13. # 尝试删除一个对象的已有属性
  14. delattr(p, "hobby")
  15. # print(p.hobby)
  16. # 抛出一个异常:AttributeError: 'Person' object has no attribute 'hobby'
  17.  
  18. # 尝试删除一个对象没有的属性
  19. # delattr(p, "gennder")
  20. # 抛出一个异常: AttributeError: gennder

结论:
当使用delattr()函数删除对象的属性后, 我们就无法再访问该属性了. 另外, 我们不能删除对象所没有的属性.

九. 异常处理

待补充

参考资料: 错误处理

十. MD5加密

步骤说明:

  1. # 1. 引入模块hashlib
  2. import hashlib
  3.  
  4. # 2. 创建一个MD5对象
  5. obj = hashlib.md5(b"complexity") # 这里的complexity是可以更改的, 它的作用是让我们的密文更加难以被碰撞到
  6.  
  7. # 3. 把要加密的内容转换成字节(byte)的形式交给MD5对象
  8. obj.update("encrypted_content".encode("utf-8"))
  9.  
  10. # 4. 获取密文
  11. val = obj.hexdigest()
  12. print(val)
  13. # 打印结果是: acff9466e8cd1867e0a9d90755b55638 , 它就是"encrypted_content"的MD5密文

实例应用:

  1. # 定义一个函数, 用于MD5加密
  2. def my_md5(val):
  3. obj = hashlib.md5(b"complexity") # 创建一个MD5对象
  4. obj.update(val.encode("utf-8")) # 把要加密的内容转换成字节的形式交给该MD5对象
  5. val = obj.hexdigest() # 使用hexdigest()函数获取密文, 并将之赋给变量val
  6. return val # 返回密文

十一. 日志处理

Python之日志处理(logging模块)

十二. super()的用法

1. 回顾 -- 继承是什么?

待补充

2. MRO(method resolution order)

(1)经典类MRO

待补充

(2)新式类MRO

待补充

3. super()的具体用法

待补充

Python 面向对象(下)的更多相关文章

  1. python面向对象(下)

    继承 继承描述了基类的属性如何"遗传"给派生类.一个子类可以继承它的基类的任何属性,不管是数据属性还是方法.创建子类的语法看起来与普通(新式)类没有区别,一个类名,后跟一个或多个需 ...

  2. Python开发【第七篇】:面向对象 和 python面向对象进阶篇(下)

    Python开发[第七篇]:面向对象   详见:<Python之路[第五篇]:面向对象及相关> python 面向对象(进阶篇)   上一篇<Python 面向对象(初级篇)> ...

  3. Python面向对象编程(下)

    本文主要通过几个实例介绍Python面向对象编程中的封装.继承.多态三大特性. 封装性 我们还是继续来看下上文中的例子,使用Student类创建一个对象,并修改对象的属性.代码如下: #-*- cod ...

  4. Python面向对象之反射,双下方法

    一. 反射 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省).这一概念的提出很快引发了计算机科学领域关于应用反射性的研究.它首先被程序 ...

  5. Python面向对象06 /元类type、反射、函数与类的区别、特殊的双下方法

    Python面向对象06 /元类type.反射.函数与类的区别.特殊的双下方法 目录 Python面向对象06 /元类type.反射.函数与类的区别.特殊的双下方法 1. 元类type 2. 反射 3 ...

  6. python 面向对象专题(六):元类type、反射、函数与类的区别、特殊的双下方法

    目录 Python面向对象06 /元类type.反射.函数与类的区别.特殊的双下方法 1. 元类type 2. 反射 3. 函数与类的区别 4. 特殊的双下方法 1. 元类type type:获取对象 ...

  7. python 面向对象初级篇

    Python 面向对象(初级篇) 概述 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类和封装,让开发" ...

  8. Python 面向对象 基础

    编程范式概述:面向过程 和 面向对象 以及函数式编程 面向过程:(Procedure Oriented)是一种以事件为中心的编程思想. 就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现 ...

  9. python面向对象进阶(八)

    上一篇<Python 面向对象初级(七)>文章介绍了面向对象基本知识: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使 ...

随机推荐

  1. asyncio模块实现线程的嵌套和穿插

    import asyncio import time now = lambda :time.time() async def cpc_1(x): print('正在烙比萨饼,预计{}分钟'.forma ...

  2. bzoj1797: [Ahoi2009]Mincut 最小割(网络流,缩点)

    传送门 首先肯定要跑一个最小割也就是最大流 然后我们把残量网络tarjan,用所有没有满流的边来缩点 一条边如果没有满流,那它就不可能被割了 一条边如果所属的两个强联通分量不同,它就可以被割 一条边如 ...

  3. 洛谷 P1600 天天爱跑步(LCA+乱搞)

    传送门 我们把每一条路径拆成$u->lca$和$lca->v$的路径 先考虑$u->lca$,如果这条路径会对路径上的某一个点产生贡献,那么满足$dep[u]-dep[x]=w[x] ...

  4. Codeforces Round #589 (Div. 2) D. Complete Tripartite(染色)

    链接: https://codeforces.com/contest/1228/problem/D 题意: You have a simple undirected graph consisting ...

  5. Codeforces Round #590 (Div. 3) B2. Social Network (hard version)

    链接: https://codeforces.com/contest/1234/problem/B2 题意: The only difference between easy and hard ver ...

  6. Python 3 格式化字符串的几种方法!

    Python 3 格式化字符串的几种方法! %s和%d,%s是用来给字符串占位置,%d是给数字占位置,简单解释下: a = 'this is %s %s' % ('an','apple') 程序输出的 ...

  7. 公共钥匙盒(CCF)【模拟】

    问题描述 有一个学校的老师共用N个教室,按照规定,所有的钥匙都必须放在公共钥匙盒里,老师不能带钥匙回家.每次老师上课前,都从公共钥匙盒里找到自己上课的教室的钥匙去开门,上完课后,再将钥匙放回到钥匙盒中 ...

  8. PHP mysqli_fetch_row() 函数

    定义和用法 mysqli_fetch_row() 函数从结果集中取得一行,并作为枚举数组返回. <?php // 假定数据库用户名:root,密码:123456,数据库:RUNOOB $con= ...

  9. @Autowired @Primary @Qualifier

    1 2 3 4 5

  10. luogu 4047 [JSOI2010]部落划分 最小生成树

    最小生成树或者二分都行,但是最小生成树会好写一些~ Code: #include <bits/stdc++.h> #define ll long long #define N 100000 ...