python面向对象 : 反射和内置方法

时间:2021-11-05 22:22:43

一. 反射

1. isinstance()和issubclass()

  isinstance( 对象名, 类名) : 判断对象所属关系,包括父类  (注:type(对象名) is 类名 : 判断对象所属关系,只包括当前的类.)

  issubclass(类名, 类名) : 判断类与类之间的继承关系

class A:
pass class B(A):
pass b = B()
print(isinstance(b, B)) # True 判断对象b是否属于B类
print(isinstance(b, A)) # True 判断对象b是否属于A类
print(type(b) is B) # True 判断对象b是否属于B类
print(type(b) is A) # False 判断对象b是否属于A类 print(issubclass(A, B)) # False 判断A是不是B的子类
print(issubclass(B, A)) # True 判断B是不是A的子类

2. 反射

  反射 : 用字符串数据类型的变量名来访问这个变量的值. python中的一切事物都是对象(都可以使用反射)

  反射的方法 : getattr , hasattr,  setattr,  delattr

(1) getattr

  getattr 接收2个参数,前面的是一个对象或者模块,后面的是一个字符串.

  语法 : 命名空间.XXX == getattr(命名空间,'XXX')

#从类的角度看:

class A:
name = 'jack'
@classmethod
def func(cls):
print(666)
@staticmethod
def func1():
print(777) # 反射查看静态属性
print(A.name) # jack
print(getattr(A, 'name')) # jack
# 反射调用方法
A.func() #
print(getattr(A, 'func')) # <bound method A.func of <class '__main__.A'>> 内存地址
getattr(A, 'func')() # 666 类方法 A.func1() #
print(getattr(A, 'func1')) # <function A.func1 at 0x000002436F709620> 内存地址
getattr(A, 'func1')() # 777 静态方法
# 从对象的角度来看

class A:
NAME = 'STEVE' # 全局变量和类中的静态属性最好全大写 @classmethod
def func(cls):
print(666) @staticmethod
def func1():
print(777) a = A()
# 反射查看静态属性
print(getattr(a, 'NAME')) # STEVE
# 反射调用方法
# 类方法
getattr(a, 'func')() #
# 静态方法
getattr(a, 'func1')() #
# 从模块的的角度

  # 导入系统模块
import os # 导入os模块 os模块是别人写好的python代码的结合
os.rename('', 'hello') # 把文件为'12'的文件名改为'hello'
getattr(os, 'rename')('hello', '') # 把文件为'hello'的文件名改为'12' ==>> os.rename # 导入自己的模块 def func1():
print(666)
def func2():
print(777) import sys # 是一个模块,这个模块里的所有的方法都是和python解释器相关的
print(sys.modules) # 这个方法 表示所有在当前这个python程序中导入的模块
# 可以找到本文件的模块地址(字典类型): '__main__' from 'D:/pycharm/练习/week05/new21.py'>
print(sys.modules['__main__']) # <module '__main__' from 'D:/pycharm/练习/week05/new21.py'>
file = sys.modules['__main__']
file.func1() #
file.func2() #
getattr(file, 'func1')() #
getattr(file, 'func2')() #

(2) hasattr

class A:
name = 'tom'
def __init__(self):
self.age = 18
a = A() print(hasattr(A, 'name')) # True 判断A类是否含有name属性
print(hasattr(a, 'age')) # True 判断对象a是否含有age属性
print(hasattr(a,'sex')) # False

(3) setattr , delattr

class A:
def __init__(self,name):
self.name = name a = A('tom')
setattr(a,'name', 'jack') # 把对象a的属性name的值改成'jack'
print(a.name) # jack
print(a.__dict__) # {'name': 'jack'} delattr(a,'name') # 删除对象a的name属性
print(a.__dict__) # {}

二. 内置方法

格式 :   __名字__              称呼 : 类中的特殊方法\内置方法 双下方法 魔术方法 (magic_method)

  类中的每一个双下方法都有它自己的特殊意义 , 所有的双下方法没有需要你在外部直接调用的, 而是总有一些其他的内置函数特殊的语法来自动触发这些双下方法

1. __call__

  功能 : 对象后面加括号,触发执行。即:对象() 或者 类()()

class A:
DAY = 'MONDAY'
def __call__(self):
print('') a = A()
a() # 666 自动执行__call__方法
A()() #

2. __len__

class A:
def __init__(self):
self.lst = [1, 2, 3, 4, 5, 6, 7]
def __len__(self):
print(666)
return len(self.lst) a = A() # 实例化对象
print(len(a)) # 7 len()自动执行__len__方法

3. __str__

class A:
def __str__(self):
return '%s %s %s %s %s' %(self.name, self.age, self.sex, self.height, self.weight)
def __init__(self, name, age, sex, height, weight):
self.name = name
self.age = age
self.sex = sex
self.height = height
self.weight = weight a = A('jack', 18, '男', 55, 1.85)
print(a) # print一个对象相当于调用一个对象的__str__方法
# jack 18 男 55 1.85
print(str(a)) # 内置的数据类型,内置的类,相当于执行__str__
# jack 18 男 55 1.85
print('1号: %s' %a) # 1号: jack 18 男 55 1.85

4. __new__

  __new__ : 构造方法

  在实例化之后,__init__之前先执行new来创建一块空间

class A:
def __new__(cls, *args, **kwargs):
obj = object.__new__(cls) # A类没有__new__,只能去找object里找
print('第一步')
return obj
def __init__(self):
print('第二步')
a = A() # 先执行__new__方法,再执行__init__方法
# 第一步
# 第二步

  单例类

# 单粒类 : 只能实现一个实例化对象空间的类
class A:
__INSTANCE = None
def __new__(cls):
if not cls.__INSTANCE :
cls.__INSTANCE = object.__new__(cls)
return cls.__INSTANCE
def __init__(self):pass a1 = A()
a2 = A()
a3 = A()
print(a1) # <__main__.A object at 0x000002096E378B38>
print(a2) # None
print(a3) # None

5. __repr__

class A:
def __init__(self, name):
self.name = name
def __repr__(self):
return self.name
a = A('jack')
print(a) # jack 自动执行了__repr__方法

  print()也会执行__str__方法,再把__str__加进程序看看

class A:
def __init__(self, name):
self.name = name
def __str__(self):
return '执行str方法%s ' % self.name
def __repr__(self):
return '执行repr方法%s ' % self.name
a = A('jack')
print(a) # 执行str方法jack
print(str(a)+'\t' + repr(a)) # 执行str方法jack 执行repr方法jack
print('%s*****%r' % (a, a)) # 执行str方法jack *****执行repr方法jack

  __repr__ 和 __str__ 的区别与联系 :

    __str__ : str(obj),要求必须实现了__str__,要求这个方法的返回值必须是字符串str类型
    print , %s, str直接执行__str__ __repr__: 是__str__的备胎.如果有__str__方法,那么print %s str都先去执行__str__方法,并且使用__str__的返回值. 如果没有__str__, 那么 print %s str都会执行repr
   repr(obj),%r直接执行__repr__
# 子类没有__str__但是有__repr__,父类有__str__时
class A:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return self.age
class B(A):
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
return self.name b = B('jack','')
print(b) # 18 先找本类的__str__ ,子类没有再找父类的__str__,父类没有再找子类的__repr__
  在子类中使用__str__, 先找子类的__str__, 没有的话要向上找,只要父类不是object, 就执行父类的__str__, 但是如果出了object之外的父类都没有__str__方法,就执行
子类的__repr__方法,如果子类也没有,还要向上继续找父类中的__repr__方法. 一直找不到 再执行object类中的__str__方法.
6. __del__ : 析构方法
class A:
def __init__(self, name):
self.name = name
def __del__(self):
print(666)
a = A('jack')
print(a.name) # jack
del a.name # 666 删除对象a的name属性, 自动触发__del__方法,然后进行删除操作
# print(a.name) # 报错,对象a已经没有name属性

7. item系列

类的实例属性是字典的时候,使用以下三个方法:

__getitem__() :返回当前的实例属性的字典值
__setitem__():属性中的key和value重新赋值
__delitem__():删除实例属性中的某个字典key和value值
class A:
def __init__(self, name):
self.name = name
def __getitem__(self, item):
return getattr(self, item)
def __setitem__(self, key, value):
setattr(self, key, value)
def __delitem__(self, key):
delattr(self, key) a = A('jack')
a['k'] = 'v' # 触发 __setitem__
print(a['k']) # 触发 __getitem__
del a['k'] # 触发 __delitem__ class A:
def __init__(self, lst):
self.lst = lst
def __getitem__(self, item):
print(self.lst[item])
def __setitem__(self, key, value):
self.lst[key] = value
def __delitem__(self, key):
self.lst.pop(key)
a = A([0, 1, 2, 3, 4, 5])
a[3] #
a[1] = 'j'
print(a.lst) # [0, 'j', 2, 3, 4, 5]
del a[4]
print(a.lst) # [0, 'j', 2, 3, 5]

8. __eq__  定义等于操作符(==)的行为。

class A:
def __init__(self, name):
self.name = name
def __eq__(self, other):
if self.name == other.name:
return True
else:
return False
a1 = A('jack')
a2= A('tom')
a3 = A('jack') print(a1 == a2) # False == 自动触发__eq__
print(a1 == a3) # True

9. __hash__

# 对同一个值在多次执行python代码的时候hash值是不同
# 但是对同一个值 在同一次执行python代码的时候hash值永远不变 print(hash('abc'))
print(hash('abc'))
print(hash('abc'))
print(hash('abc'))
# 第一次运行
#
#
#
#
# 第二次运行
#
#
#
#

  字典的寻址和集合的去重都是通过hash算法完成的.

  字典 : 通过哈希算法,把key值进行一次计算,算出哈希值,若是出现哈希值相同的key,则比较key值是否相同,若相同则覆盖value值,不同就二次寻址.

   集合: 通过哈希算法,把元素的值进行一次计算,若是出现哈希值相同的元素,则比较元素值是否相同,若相同后面的则覆盖前面元素的值,不同就二次寻址.

# 一个类
# 对象的属性 : 姓名 性别 年龄 部门
# 员工管理系统
# 内部转岗 python开发 - go开发
# 姓名 性别 年龄 新的部门 # 5个员工
# 如果几个员工对象的姓名和性别相同,这是一个人
# 请对这5个员工做去重
class Staff:
def __init__(self, name, sex, age, partment):
self.name = name
self.sex = sex
self.age = age
self.partment = partment def __hash__(self):
return hash(self.name + self.sex)
# hash('%s%s'%(self.name,self.sex))
# hash(self.name, self.sex) # 报错,因为给了两个值 def __eq__(self, other):
if self.name == other.name and self.sex == other.sex:
return True
else:
return False s1 = Staff('jack', '男', 18, 'sales_department')
s2 = Staff('tom', '男', 22, 'finace_departmrnt')
s3 = Staff('vicky', '女', 20, 'marketing_department')
s4 = Staff('jack', '男', 25, 'personnel_department')
s5 = Staff('vicky', '女', 22, 'production_department')
lst = [s1, s2, s3, s4, s5]
print(lst)
staff_set = set(lst) # 去重操作
print(staff_set)
for person in staff_set:
print(person.__dict__)
# {'name': 'vicky', 'sex': '女', 'age': 20, 'partment': 'marketing_department'}
# {'name': 'tom', 'sex': '男', 'age': 22, 'partment': 'finace_departmrnt'}
# {'name': 'jack', 'sex': '男', 'age': 18, 'partment': 'sales_department'}
 

python面向对象 : 反射和内置方法的更多相关文章

  1. python 面向对象反射以及内置方法

    一.反射 什么是反射:可以用字符串的方式去访问对象的属性,调用对象的方法(但是不能去访问方法),python中一切皆对象,都可以使用放射. 反射的四种方法: hasattr:hasattr(objec ...

  2. 《Python》反射、内置方法(&lowbar;&lowbar;str&lowbar;&lowbar;,&lowbar;&lowbar;repr&lowbar;&lowbar;)

    一.反射 通过字符串的形式操作对象相关的属性.(使用字符串数据类型的变量名来获取这个变量的值) Python中的一切事物都是对象(都可以使用反射) 反射类中的变量 反射对象中的变量 反射模板中的变量 ...

  3. Python面向对象编程及内置方法

    在程序开发中,要设计一个类,通常需要满足以下三个要求: [1]类名 这类事物的名字,满足大驼峰命名法 [2]属性 这类事物具有什么样的特征 [3]方法 这类事物具有什么样的行为 定义简单的类: 定义只 ...

  4. day26&period;面向对象-反射封装内置方法

    封装 隐藏对象的属性和实现细节,近对外提供公共访问方式 广义:代码保护,面向对象思想 狭义:将属性,方法隐藏起来 class Person: __key = 123456 # 私有的静态属性 def ...

  5. python 面向对象 类的内置方法

    判断是不是类cls的对象 class A: pass a = A() print(isinstance(a,A)) 判断类sub是不是super的子类 class A: pass class B(A) ...

  6. python面向对象--类的内置方法

    #isinstance(obj,cls)判断obj是否是类cls的实例 #issubclass(cls,cls1)判断cls是否是cls1的子类或派生类 class Foo: pass class B ...

  7. python 面向对象之反射及内置方法

    面向对象之反射及内置方法 一.静态方法(staticmethod)和类方法(classmethod) 类方法:有个默认参数cls,并且可以直接用类名去调用,可以与类属性交互(也就是可以使用类属性) 静 ...

  8. Python反射和内置方法(双下方法)

    Python反射和内置方法(双下方法) 一.反射 什么是反射 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省).这一概念的提出很快引发 ...

  9. 面向对象(五)——isinstance与issubclass、反射、内置方法

    isinstance与issubclass.反射.内置方法 一.isinstance与issubclass方法 1.isinstance是用来判断对象是否是某个类 isinstance(obj,cla ...

随机推荐

  1. 中小网站如何使用谷歌Adsence国际化优势赚钱?

    劲捷电子信息有限公司是一家拿了美国风险投资的互联网公司.他的创办人祁劲松2005年加入AdSense,迄今收获颇丰,为此他还写了一本 <Google AdSense实战宝典>.在祁劲松看来 ...

  2. &lbrack;译&rsqb;Mongoose指南 - Population

    MongoDB没有join, 但是有的时候我们需要引用其它collection的documents, 这个时候就需要populate了. 我们可以populate单个document, 多个docum ...

  3. Nginx反向代理到Tomcat服务器

    在实际生产中,Tomcat服务器一般不单独使用在项目中,对于静态资源的响应Nginx表现的比较好,另外由于nginx是专门用于反向代理的服务器,所以很容易实现将java的请求转发到后端交给tomcat ...

  4. Android屏幕旋转总结

    转自:http://www.myexception.cn/operating-system/1452058.html 1. ProjectConifg.mk中定义宏MTK_LCM_PHYSICAL_R ...

  5. ListBox实现拖拽排序功能

    1.拖拽需要实现的事件包括: PreviewMouseLeftButtonDown LBoxSort_OnDrop 具体实现如下: private void LBoxSort_OnPreviewMou ...

  6. Spring对hibernate的事物管理

    把Hibernate用到的数据源Datasource,Hibernate的SessionFactory实例,事务管理器HibernateTransactionManager,都交给Spring管理.一 ...

  7. 我的前端之旅--SeaJs基础和spm编译工具运用&lbrack;图文&rsqb;

    标签:seajs   nodejs   npm   spm   js 1. 概述 本文章来源于本人在项目的实际应用中写下的记录.因初期在安装和使用Seajs和SPM的时候,有点不知所措的经历.为此,我 ...

  8. socket 编程基础

    一.Socket简介 Socket是进程通讯的一种方式,即调用这个网络库的一些API函数实现分布在不同主机的相关进程之间的数据交换. 几个定义: (1)IP地址:即依照TCP/IP协议分配给本地主机的 ...

  9. &lpar;网页&rpar;javaScript增删改查&lpar;转&rpar;

    转自CSDN: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> ...

  10. 『编程题全队』alpha阶段项目复审

    小组的名字和链接 优点 缺点,bug 报告 最终名次 Gakki赛高 (1)支持注册账号和账号管理(2) 支持自动登录,提供便捷性(3)题目不重复且题目答案准确(4)支持排行榜统计功能(5)自己设计算 ...