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

一、反射

  1. 什么是反射

    反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。

  2. Python面向对象中的反射

    通过字符串的形式操作对象相关的属性。Python中的一切事物都是对象(都可以使用反射)

    四个可以实现自省的函数:

    1. hasattr():检测是否含有某属性

      1. class Foo:
      2. def __init__(self, name, age):
      3. self.name = name
      4. self.age = age
      5. def func(self):
      6. pass
      7. # 检测是否含有某属性
      8. print(hasattr(Foo, "func")) # True
      9. f = Foo("dogfa", 18)
      10. print(hasattr(f, "name")) # True
      11. print(hasattr(f, "gender")) # False
    2. getattr():获取属性

      1. class Foo:
      2. def __init__(self, name, age):
      3. self.name = name
      4. self.age = age
      5. def func(self):
      6. pass
      7. @staticmethod
      8. def staticfunc():
      9. print("嘿嘿嘿")
      10. # 获取属性
      11. f = getattr(Foo, "staticfunc")
      12. print(f) # <function Foo.staticfunc at 0x0000028DD8EB9D08>
      13. f() # 嘿嘿嘿
      14. # 如果要获取的属性不存在那么就会报错
      15. f2 = getattr(Foo, "func1") # AttributeError: type object 'Foo' has no attribute 'func1'
    3. setattr():设置属性

      1. class Foo:
      2. def __init__(self, name, age):
      3. self.name = name
      4. self.age = age
      5. def func(self):
      6. pass
      7. @staticmethod
      8. def staticfunc():
      9. print("嘿嘿嘿")
      10. f = Foo("dogfa", 18)
      11. print(f.__dict__) # {'name': 'dogfa', 'age': 18}
      12. setattr(f, "name", f.name + "sb")
      13. print(f.__dict__) # {'name': 'dogfa_sb', 'age': 18}
    4. defattr():删除属性

      1. class Foo:
      2. def __init__(self, name, age):
      3. self.name = name
      4. self.age = age
      5. def func(self):
      6. pass
      7. @staticmethod
      8. def staticfunc():
      9. print("嘿嘿嘿")
      10. f = Foo("dogfa", 18)
      11. print(f.__dict__) # {'name': 'dogfa', 'age': 18}
      12. delattr(f, "name")
      13. print(f.__dict__) # {'age': 18}
      14. # delattr(f, "gender") # 删除不存在的属性时会报错
  3. 使用反射的场景

    1. 对对象的反射
    2. 对类的反射
    3. 其它模块的反射
    4. 当前模块的反射

二、内置方法

  1. 函数与方法的区别

    在说方法之前我们先来说一下在Python中函数和方法的区别。

    1. # 通过导入types模块来验证
    2. from types import FunctionType, MethodType
    3. def func():
    4. pass
    5. class A:
    6. def func(self):
    7. pass
    8. @staticmethod
    9. def func2():
    10. pass
    11. obj = A()
    12. # FunctionType:函数 MethodType:方法
    13. print(isinstance(func, FunctionType)) # True
    14. print(isinstance(A.func, FunctionType)) # True
    15. print(isinstance(obj.func, FunctionType)) # False
    16. print(isinstance(obj.func, MethodType)) # True
    17. print(isinstance(A.func2, FunctionType)) # True
    18. print(isinstance(obj.func2, FunctionType)) # True
    19. # 通过打印函数(方法)名验证
    20. from types import FunctionType, MethodType
    21. def func():
    22. pass
    23. class A:
    24. def func(self):
    25. pass
    26. @staticmethod
    27. def func2():
    28. pass
    29. obj = A()
    30. print(func) # <function func at 0x000002013BC32E18>
    31. print(A.func) # <function A.func at 0x000002013BF6A598>
    32. print(obj.func) # <bound method A.func of <__main__.A object at 0x000002013BDF7DD8>>

    总结:

    (1)函数的是显式传递数据的。如我们要指明为len()函数传递一些要处理数据。

    (2)函数则跟对象无关。

    (3)方法中的数据则是隐式传递的。

    (4)方法可以操作类内部的数据。

    (5)方法跟对象是关联的。如我们在用strip()方法时,都是要通过str对象调用,比如我们有字符串s,然后s.strip()这样调用。是的,strip()方法属于str对象。

    (6)静态方法就是函数

  2. 内置方法(双下方法)

    定义:双下方法是特殊方法,他是解释器提供的 由爽下划线加方法名加双下划线 __方法名__的具有特殊意义的方法,双下方法主要是Python源码程序员使用的,我们在开发中尽量不要使用双下方法,但是深入研究双下方法,更有益于我们阅读源码。

    调用:不同的双下方法有不同的触发方式,就好比盗墓时触发的机关一样,不知不觉就触发了双下方法,例如:__init__

    1. item系列

      1. class Foo:
      2. def __init__(self, name, age):
      3. self.name = name
      4. self.age = age
      5. def __getitem__(self, item):
      6. print("执行obj['key']时会执行我")
      7. return getattr(self, item)
      8. def __setitem__(self, key, value):
      9. print("执行obj['key'] = value 时会执行我")
      10. setattr(self, key, value)
      11. def __delitem__(self, key):
      12. print("执行del['key']时会执行我")
      13. delattr(self, key)
      14. obj = Foo("oldwang", 20)
      15. print(obj["name"])
      16. # 执行obj['key']时会执行我
      17. # oldwang
      18. obj["name"] = "oldniu"
      19. print(obj["name"])
      20. # 执行obj['key'] = value 时会执行我
      21. # 执行obj['key']时会执行我
      22. # oldniu
      23. print(obj.__dict__)
      24. del obj["name"]
      25. print(obj.__dict__)
      26. # {'name': 'oldniu', 'age': 20}
      27. # 执行del['key']时会执行我
      28. # {'age': 20}
    2. __del__

      析构方法,当对象在内存中被释放时,自动触发执行。

      注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。

      1. class FileHandle:
      2. def __init__(self, file_path):
      3. self.f = open(file_path, mode="r", encoding="utf-8")
      4. def read(self):
      5. return self.f.read(1024)
      6. def __del__(self):
      7. # 在程序执行完时释放文件句柄
      8. self.f.close()
      9. f = FileHandle("file/userinfo")
      10. print(f.read())
    3. __new__

      1. # 单例类
      2. class Single:
      3. __isinstance = None
      4. def __new__(cls, *args, **kwargs):
      5. if not cls.__isinstance:
      6. cls.__isinstance = object.__new__(cls)
      7. return cls.__isinstance
      8. return cls.__isinstance
      9. one = Single()
      10. two = Single()
      11. print(one is two) # True
    4. __call__

      对象后面加括号,触发执行。

      注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 call 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()

      1. class Foo:
      2. def __call__(self, *args, **kwargs):
      3. print("执行__call__")
      4. f = Foo()
      5. f() # 执行__call__
      6. # 还可以这样写
      7. Foo()()
    5. __len__

      1. class Foo:
      2. def __init__(self, name, age):
      3. self.name = name
      4. self.age =age
      5. def __len__(self):
      6. return len(self.__dict__)
      7. f = Foo("dogfa", 18)
      8. print(len(f)) # 2
    6. __hash__

      1. class A:
      2. def __init__(self):
      3. self.a = 1
      4. self.b = 2
      5. def __hash__(self):
      6. return hash(str(self.a)+str(self.b))
      7. a = A()
      8. print(hash(a))
    7. __eq__

      1. class A:
      2. def __init__(self):
      3. self.a = 1
      4. self.b = 2
      5. def __eq__(self,obj):
      6. if self.a == obj.a and self.b == obj.b:
      7. return True
      8. a = A()
      9. b = A()
      10. print(a == b) # True

三、其它

  1. # 有一个员工类,1000个员工对象,对象属性有姓名,性别,年龄,部门,
  2. # 按姓名,性别对1000个对象去重
  3. class Employee:
  4. def __init__(self, name, age, gender, department):
  5. self.name = name
  6. self.age = age
  7. self.gender = gender
  8. self.department = department
  9. def __hash__(self):
  10. return hash("{0}{1}".format(self.name, self.gender))
  11. def __eq__(self, other):
  12. if self.name == other.name and self.gender == other.gender:
  13. return True
  14. employee_list = []
  15. for i in range(250):
  16. employee_list.append(Employee("dogfa", i, "male", "python" + str(i)))
  17. for i in range(250):
  18. employee_list.append(Employee("djb", i, "female", "php" + str(i)))
  19. for i in range(250):
  20. employee_list.append(Employee("oldniu", i, "male", "java" + str(i)))
  21. for i in range(250):
  22. employee_list.append(Employee("cdj", i, "female", "go" + str(i)))
  23. for employee_obj in set(employee_list):
  24. print(employee_obj.__dict__)

Python反射和内置方法(双下方法)的更多相关文章

  1. python 反射和内置方法

    一.isinstance和issubclass class Foo: pass class Son(Foo): pass s = Son() #判断一个对象是不是这个类的对象,传两个参数(对象,类) ...

  2. Python day12部分内置函数的常见方法

    #内置函数 print(abs(-1))#绝对值 ']))#判断list的真假,都真则真,有一个假也是假 print(any(''))#有一个真就真,全假则假 print(bin(3))#十进制转换二 ...

  3. Python面向对象之魔法方法/双下方法

    1.__new__ and __init__ 这两个方法都是在实例化的时候执行,__new__ 在 __init__ 之前执行,并且 如果实例化的时候封装属性,__new__也是必须要传的,而且__n ...

  4. day27:反射和双下方法

    1, # 面向对象的三大特性:继承,多态和封装 # 继承: # 单继承: **** # 父类(超类,基类) # 子类(派生类) 派生方法和派生属性 # 子类的对象在调用方法和属性:先用自己的,自己没有 ...

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

    一. 反射 1. isinstance()和issubclass() isinstance( 对象名, 类名) : 判断对象所属关系,包括父类  (注:type(对象名) is 类名 : 判断对象所属 ...

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

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

  7. 反射,内置方法,__str__ __repr__

    反射 反射用到的mmp模块 def wahaha():print('wahaha') class QQxing: def __init__(self,name): self.name = name d ...

  8. python之路-双下方法

    双下方法 定义: 双下方法是特殊方法,他是解释器提供的,由双下线加方法名加双下划线 __方法名__具有特殊意义的方法 双下方法主要是Python源码程序员使用的,元编程 我们在开发中尽量不要使用双下方 ...

  9. Python面向对象 | 双下方法

    定义:双下方法是特殊方法,他是解释器提供的.由双下划线+方法名+双下划线 .它具有特殊意义的方法,双下方法主要是python源码程序员使用的,我们在开发中尽量不要使用双下方法,但是深入研究双下方法,更 ...

随机推荐

  1. 【实战】Vue全家桶(vue + axios + vue-router + vuex)搭建移动端H5项目

    使用Vue全家桶开发移动端页面. 本博文默认已安装node.js. github链接 一.准备工作 安装vue npm install vue 安装脚手架vue-cli npm install -g ...

  2. js即时函数在异步回调中的运用

    在编程中我们会接触到循环和异步编程的情况,这时异步回调执行逻辑就会出现问题.我们用setTimeout来模拟异步的: for(var i=0;i<3;i++){ setTimeout(funct ...

  3. Java基础系列 - 接口(功能,用途和优势)

    package com.test1; /** * 接口的使用 */ public class test1 { public static void main(String[] args) { //创建 ...

  4. 【转】Python基础-字符串

    原文地址http://blog.chinaunix.net/uid-21169302-id-446256.html Python-String-Function 字符串中字符大小写的变换: * S.l ...

  5. java打jar包与找不到依赖包详解

    eclipse打jar包与找不到依赖包详解 eclipse打工具jar 1.项目右键-->export -->搜索java 2.选择JAR file 3.打包 eclipse打包可执行ja ...

  6. Python 中路径的有效使用

    import arcpy arcpy.GetCount_management("c:/temp/streams.shp") arcpy.GetCount_management(&q ...

  7. 自定义ObjectAnimator属性实现

    package com.loaderman.customviewdemo; import android.animation.ObjectAnimator; import android.graphi ...

  8. webpack——Modules && Hot Module Replacement

    blog:JavaScript Module Systems Showdown: CommonJS vs AMD vs ES2015 官网链接: Modules 官网链接:Hot Module Rep ...

  9. ElasticSearch——冷热(hot&warm)架构部署

    背景 最近在做订单数据存储到ElasticSearch,考虑到数据量比较大,采用冷热架构来存储,每月建立一个新索引,数据先写入到热索引,通过工具将3个月后的索引自动迁移到冷节点上. ElasticSe ...

  10. Composer更新慢的终极解决方案-转

    转自:http://blog.csdn.net/fishermanmax/article/details/51975692 Packagist 镜像 请各位使用本镜像的同学注意: 本镜像已经依照 co ...