一、issubclass/type/isinstance(***)

  1、issubclass(参数1, 参数2):检查第一个参数是否是第二个参数的 子子孙孙类,如下示例:

    class Base(object):
pass class Foo(Base):
pass class Bar(Foo):
pass print(issubclass(Bar, Foo)) # True
print(issubclass(Bar, Base)) # True

  2、type():获取当前对象时由哪个类创建,如下示例:

    # #####示例一:判断一个参数是不是某一个指定类的对象
class Foo(object):
pass obj = Foo()
print(obj,type(obj))
# <__main__.Foo object at 0x0000000002618F60> <class '__main__.Foo'>
if type(obj) == Foo: # 判断一个参数是不是某一个指定类的对象
print('obj是Foo类型') # #####示例二:练习题:判断函数的参数分别是哪个类的对象
class Foo(object):
pass class Bar(object):
pass def func(*args):
foo_counter = 0
bar_counter = 0
for item in args:
if type(item) == Foo:
foo_counter += 1
elif type(item) == Bar:
bar_counter += 1
return foo_counter, bar_counter print(func(Foo(), Bar(), Foo())) # (2, 1)
    # 补充:示例三:如何判断参数是不是一个类
class Foo(object):
pass
obj = Foo()
print(type(Foo) == type) # True
print(type(obj) == type) # False

  3、isinstance(参数1, 参数2):检查第一个参数是否是第二个参数的实例,如下示例:

    # #####示例一:判断一个参数是不是某一个指定类或其父类的对象
class Base:
pass
class Foo(Base):
pass
class Bar(Foo):
pass
obj1 = Bar()
print(isinstance(obj1, Bar)) # True
print(isinstance(obj1, Foo)) # True
print(isinstance(obj1, Base)) # True obj2 = Foo()
print(isinstance(obj2, Bar)) # False

二、用科学的方式判断是函数和方法(*)

  一般我们笼统的称定义在类中的函数为方法,定义在类外的就是函数,其实是不太严谨的,如下示例:

    # #####示例一:如何看得出是函数还是方法
def func():
pass
class Foo(object):
def inner(self):
pass
@staticmethod
def detail():
pass
print(func) # <function func at 0x00000000028C99D8> 是函数 obj = Foo()
print(obj.inner) # 是方法
# <bound method Foo.inner of <__main__.Foo object at 0x00000000028D1208>>
print(Foo.detail) # <function Foo.detail at 0x00000000028F9AE8> 是函数
print(obj.detail) # <function Foo.detail at 0x00000000028F9AE8> 是函数

如何看得出是函数还是方法

  其实,在python中,一切皆对象,只要是对象,它就有对应的类,函数是FunctionType创建的,方法是由MethodType创建的,所以,我们可以按照如下示例判断是函数还是方法:

    # #####示例二
from types import MethodType,FunctionType
def check(arg):
"""
检查arg是方法还是函数?
"""
if isinstance(arg,MethodType):
print('arg是一个方法')
elif isinstance(arg,FunctionType):
print('arg是一个函数')
else:
print('不知道是什么')
check(func) # arg是一个函数
check(obj.inner) # arg是一个方法
    # #####示例三:是不是方法跟写在哪里没关系,跟调用有关系
class Foo(object):
def f1(self):
pass obj = Foo()
obj.f1() # 把f1当做方法,python自动传self值
print(obj.f1)
# <bound method Foo.f1 of <__main__.Foo object at 0x0000000002724390>>
obj = Foo()
Foo.f1(obj) # 把f1当做函数,需要自己传参数
print(Foo.f1) # <function Foo.f1 at 0x0000000002791AE8>

是不是方法跟写在哪里没有关系,跟调用有关系

    # #####示例四:练习题
class Foo(object):
def f1(self):
pass
def f2(self):
pass
def f3(self):
pass
list_display = [f1,f2]
def __init__(self):
pass
for item in Foo.list_display:
print(item)
item(123) # item是函数,所以要自己传参数
# 结果为:
# <function Foo.f1 at 0x00000000029A3B70>
# <function Foo.f2 at 0x00000000029A3BF8>

练习题一

    # #####示例五
class Foo(object):
def f1(self):
pass
def f2(self):
pass
def f3(self):
pass
list_display = [f1,f2] obj = Foo()
Foo.list_display.append(obj.f3) for item in Foo.list_display:
print(item)
# 结果为:
# <function Foo.f1 at 0x0000000002973D90>
# <function Foo.f2 at 0x0000000002973E18>
# <bound method Foo.f3 of <__main__.Foo object at 0x0000000002908A90>>

练习题二

  总结:执行那个类里边的  .什么功能  的时候,如果是 对象.功能,那么这个功能就是方法。

    对象.xxx  --- >  xxx就是方法

    类.xxx    --- >  xxx就是函数

三、反射(*****)

  重点:v = getattr(obj , “func”)  # 根据字符串为参数(第二个参数),去对象(第一个参数)中寻找与之同名的成员。

应用一、首先定义一个handler模块,handler.py文件内容如下:

    f0 = 9
def f1():
print('F1')
def f2():
print('F2')
def f3():
print('F3')
def f4():
print('F4')
def f5():
print('F5')

handler.py

  现有个需求,用户输入模块中的函数名,则执行该函数,你可能会按照如下方式写代码:

    """
import handler
val = input("请输入要执行的函数:")
if val == 'f1':
handler.f1()
elif val == 'f2':
handler.f2()
elif val == 'f3':
handler.f3()
elif val == 'f4':
handler.f4()
elif val == 'f5':
handler.f5()
"""

以前的写法

  学习了反射,我们可以这样写,如下示例:

    from types import FunctionType
import handler
while True:
print("""
系统支持的函数有:
1. f1
2. f2
3. f3
4. f4
5. f5
""")
val = input("请输入要执行的函数:") if hasattr(handler, val): # 假如 val = "f1"
func_or_val = getattr(handler, val)
# 根据字符串为参数,去模块中寻找与之同名的成员。
if isinstance(func_or_val, FunctionType):
func_or_val() # 是函数则执行
else:
print(func_or_val) # 不是函数则打印出来
else:
print('handler中不存在输入的属性名')

应用二、用户登录、注销、注册程序:

    class Account(object):
func_list = ['login', 'logout', 'register']
def login(self):
"""
登录
"""
print('登录111')
def logout(self):
"""
注销
"""
print('注销111')
def register(self):
"""
注册
"""
print('注册111')
def run(self):
"""
主代码
"""
print("""
请输入要执行的功能:
1. 登录
2. 注销
3. 注册
""")
choice = int(input('请输入要执行的序号:'))
func_name = Account.func_list[choice-1] func = getattr(self, func_name) # self.login
func() obj1 = Account()
obj1.run()

反射补充:还是以引入handler模块为例:

    import handler
# hasattr
v1 = hasattr(handler,'f0')
v2 = hasattr(handler,'f1')
v3 = hasattr(handler,'f2')
v4 = hasattr(handler,'xxx')
print(v1,v2,v3,v4) # True True True False # setattr
setattr(handler,'x2',999)
v5 = getattr(handler,'x2')
print(v5) # setattr(handler,'f8',lambda x:x+1)
v6 = getattr(handler,'f8')
v7 = v6(1)
print(v7) # # delattr
delattr(handler,'f0')
# v8 = getattr(handler,'f0')
# print(v8) # AttributeError: module 'handler' has no attribute 'f0'

总结:

  getattr   # 根据字符串的形式,去对象中找成员;

  hasattr   # 根据字符串的形式,去判断对象中是否有成员;

  setattr   # 根据字符串的形式,动态的设置一个成员(内存);

  delattr   # 根据字符串的形式,动态的删除一个成员(内存);

四、补充知识点(callable)

  你见过的什么后面可以加括号?

    -  类()             -  对象()

    -  函数()           -  方法()

  以上所有都可以被调用。如何验证呢?如下示例:

    def func():
pass class Foo(object):
def __call__(self, *args, **kwargs):
pass
def func(self):
pass
obj = Foo()
print(callable(func)) # True
print(callable(Foo)) # True
print(callable(obj)) # True
print(callable(obj.func)) # True

五、特殊成员补充

    # print(对象),会自动执行__str__方法
class Foo(object):
def __init__(self):
pass
def func(self):
pass
def __str__(self):
return "F1" # 必须返回字符串
obj = Foo()
print(obj,type(obj)) # F1 <class '__main__.Foo'>

__str__

    # __doc__
class Foo(object):
"""
这里是注释
"""
def __init__(self):
pass
def func(self):
pass
def __str__(self):
return "F1" obj = Foo()
print(obj.__doc__) # 这里是注释

__doc__

    # __dict__
class Foo(object):
def __init__(self, name, age):
self.name = name
self.age = age
def func(self):
pass
obj1 = Foo('刘博文', 99)
obj2 = Foo('史雷', 89)
print(obj1.__dict__) # {'name': '刘博文', 'age': 99}
print(obj2.__dict__) # {'name': '史雷', 'age': 89}

__dict__

    # __iter__
class Foo(object):
def __init__(self,name,age):
self.name = name
self.age = age
def __iter__(self):
return iter([11,22,33])
# 生成器
# yield 11
# yield 22
# yield 33
"""
如果想要把不可迭代对象 -> 可迭代对象
1. 在类中定义__iter__方法
2. iter内部返回一个迭代器(生成器也是一种特殊迭代器)
"""
obj1 = Foo('刘博文',99)
for item in obj1:
print(item)
# 结果为:
#
#
#

__iter__

issubclass/type/isinstance、函数和方法、反射、callable、特殊成员补充的更多相关文章

  1. python--区分函数和方法, 反射

    1.  isinstance,   type,   issubclass isinstance(): 判断你给的xxx对象是否是xxxxx类型的,只支持向上判断 isinstance(object, ...

  2. python issubclass 和 isinstance函数

    Python issubclass() 函数 issubclass() 方法用于判断参数 class 是否是类型参数 classinfo 的子类. 语法: issubclass(class, clas ...

  3. python之面向对象函数与方法,反射,双下方法

    一.函数和方法 1.函数和方法的区别 函数: 全都是显性传参,手动传参,与对象无关 方法: 存在隐性传参,与对象有关 1.1通过函数名可以判断 len()就是函数 str.count()就是方法 de ...

  4. python---issubclass/type/isinstance/ 反射(内置函数getattr/delattr...)

    # 一 python面向对象-内置函数(issubclass(), type(), isinstance()) # issubclass 判断xxxx类是否是xxxx类的子类 class egg: p ...

  5. 方法和函数,isinstance/issubclass/type以及反射

    一丶,isinstance/issubclass/type 1.issubclass检查第一个参数是否是第二个参数的 子子孙孙类 class Foo(): pass class Boo(Foo): p ...

  6. 面向对象中特殊方法的补充、isinstance/issubclass/type、方法和函数、反射

    一.面向对象中特殊方法的补充 1.__str__ 能将对象名改成你想要的字符串,但是类型还是类 class Foo(object): def __init__(self): pass def func ...

  7. 绑定与非绑定方法及反射,isinstance和issubclass内置函数

    目录 绑定方法与非绑定方法 1.绑定方法 2.非绑定方法(staticmethod) isinstance和issubclass 内置函数 1.isinstance 2.issubclass 反射(面 ...

  8. python之反射机制与callattr()、issubclass()、isinstance、type()相关

    一.反射机制 * 反射可以理解为 通过字符串的形式,动态导入模块: 利用字符串的形式,在对象(模块)中操作(查找/获取/删除/添加)成员,是一种基于字符串的事件驱动! 反射机制的内置函数 # hasa ...

  9. PYTHON-绑定方法 反射 内置函数

    '''绑定方法类中定义函数分为了两大类: 1. 绑定方法 特殊之处: 绑定给谁就应该由谁来调用,谁来调用就会将谁当做第一个参数自动传入 如何用: 绑定给对象的方法: 在类中定义函数没有被任何装饰器修饰 ...

随机推荐

  1. 浅谈C语言中断处理机制

    一.中断机制 1.实现中断响应和中断返回 当CPU收到中断请求后,能根据具体情况决定是否响应中断,如果CPU没有更急.更重要的工作,则在执行完当前指令后响应这一中断请求.CPU中断响应过程如下:首先, ...

  2. 初识Quartz(二)

    简单作业: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 package quartz_pr ...

  3. java-SimpleDateFormatDemo & BirthDemo

    java日期格式设置,以及案例BirthDemo package com.example; import java.text.ParseException; import java.text.Simp ...

  4. Cassandra第一次使用

    在FreeBSD上安装Cassandra: # pkg install cassandra2找了半天Cassandra的配置文件,原来安装位置是在这: /usr/local/share/cassand ...

  5. IRQ与FIQ的区别

    1.对FIQ你必须进快处理中断请求,并离开这个模式. 2.IRQ可以被FIQ所中断,但FIQ不能被IRQ所中断,在处理FIQ时必须要关闭中断. 3.FIQ的优先级比IRQ高. 4.FIQ模式下,比IR ...

  6. 设计模式中类的关系之实现(Realization)

    实现关系是用来描述接口和实现接口的类或者构建结构之间的关系,接口是操作的集合,而这些操作就用于规定类或者构建结构的一种服务. 在接口和类之间的实现关系中,类实现了接口,类中的操作实现了接口中所声明的操 ...

  7. Eclipse中关于JRE System Library、Web App Libraries的疑惑

    当我们在Eclipse中建立java的web工程时,会产生JRE System Library和Referenced Libraries,Web App Libraries不生成,下面会 简要说明一下 ...

  8. Linux 文件管理(C语言库函数一)

    系统调用函数能够直接操作系统设备,C语言库函数是对系统调用函数的封装,增加了可移植性, C语言库函数可以在各个系统上运行,而系统调用则会因为系统不同而有一定的差别. 在读写文件这个操作上,系统函数每次 ...

  9. Eclipse 关闭项目

    Eclipse 关闭项目 为什么要关闭项目? Eclipse 工作空间包含了多个项目.一个项目可以是关闭或开启状态. 项目打开过多影响有: 消耗内存 占用编译时间:在删除项目.class 文件(Cle ...

  10. 循环杀死Mysql sleep进程脚本

    #!/bin/sh while : do n=`mysqladmin processlist -uadmin -p***|grep -i sleep |wc -l` date=`date +%Y%m% ...