issubclass/type/isinstance、函数和方法、反射、callable、特殊成员补充
一、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、特殊成员补充的更多相关文章
- python--区分函数和方法, 反射
1. isinstance, type, issubclass isinstance(): 判断你给的xxx对象是否是xxxxx类型的,只支持向上判断 isinstance(object, ...
- python issubclass 和 isinstance函数
Python issubclass() 函数 issubclass() 方法用于判断参数 class 是否是类型参数 classinfo 的子类. 语法: issubclass(class, clas ...
- python之面向对象函数与方法,反射,双下方法
一.函数和方法 1.函数和方法的区别 函数: 全都是显性传参,手动传参,与对象无关 方法: 存在隐性传参,与对象有关 1.1通过函数名可以判断 len()就是函数 str.count()就是方法 de ...
- python---issubclass/type/isinstance/ 反射(内置函数getattr/delattr...)
# 一 python面向对象-内置函数(issubclass(), type(), isinstance()) # issubclass 判断xxxx类是否是xxxx类的子类 class egg: p ...
- 方法和函数,isinstance/issubclass/type以及反射
一丶,isinstance/issubclass/type 1.issubclass检查第一个参数是否是第二个参数的 子子孙孙类 class Foo(): pass class Boo(Foo): p ...
- 面向对象中特殊方法的补充、isinstance/issubclass/type、方法和函数、反射
一.面向对象中特殊方法的补充 1.__str__ 能将对象名改成你想要的字符串,但是类型还是类 class Foo(object): def __init__(self): pass def func ...
- 绑定与非绑定方法及反射,isinstance和issubclass内置函数
目录 绑定方法与非绑定方法 1.绑定方法 2.非绑定方法(staticmethod) isinstance和issubclass 内置函数 1.isinstance 2.issubclass 反射(面 ...
- python之反射机制与callattr()、issubclass()、isinstance、type()相关
一.反射机制 * 反射可以理解为 通过字符串的形式,动态导入模块: 利用字符串的形式,在对象(模块)中操作(查找/获取/删除/添加)成员,是一种基于字符串的事件驱动! 反射机制的内置函数 # hasa ...
- PYTHON-绑定方法 反射 内置函数
'''绑定方法类中定义函数分为了两大类: 1. 绑定方法 特殊之处: 绑定给谁就应该由谁来调用,谁来调用就会将谁当做第一个参数自动传入 如何用: 绑定给对象的方法: 在类中定义函数没有被任何装饰器修饰 ...
随机推荐
- VS中 无法创建虚拟目录 本地IIS IIS Express 外部主机
从前就有个疑问了,为什么我拉取别人写好的代码后就可以在IIS里面生成一个网站呢? 这里所谓的生成网站,是指包含了所有源代码文件的网站:相对地,发布网站,就是指包含被编译的源文件所得到的DLL文件的网站 ...
- W25Q128页数和扇区数
int8_t STORAGE_GetCapacity (uint8_t lun, uint32_t *block_num, uint32_t *block_size){ *block_size = 4 ...
- rxjs来啦
var text = document.querySelector('#text'); var inputStream = Rx.Observable.fromEvent(text, 'keyup') ...
- html块级元素与内联元素的区别
1. 块级元素(block element): 概念理解:如果不用css控制,块级元素在文档流中以一行显示,及它所占的宽度为其父级元素所占的宽度,若超过宽度会重新另起一行显示,高度会随着内容高度的增 ...
- nginx 模块简介
nginx模块一般分为5类:核心模块.标准http模块.可选http模块.邮件服务模块.第三方模块. 其中核心模块和标准http模块在快速编译之后就包含在了nginx中. 主要看一下核心模块.标准ht ...
- App上架注意事项(转)
上传不出现构建版本 现在苹果要求先上传版本,然后在提交审核,但是现在经常上传完应用后,不出现构建版本,等待很久很久,也不出现,那么怎么解决,我告诉你~~尼玛的苹果是自己数据丢包了,结果就造成你不出现构 ...
- 各类 HTTP 返回状态代码详解(转)
FTP状态码 一.HTTP状态码 如果某项请求发送到您的服务器要求显示您网站上的某个网页(例如,用户通过浏览器访问您的网页或 Googlebot 抓取网页时),服务器将会返回 HTTP 状态代码以响应 ...
- Java并发编程(十四)并发容器类
同步容器将所有对容器状态的访问都串行化,以实现线程安全性.这种方法的代价是严重降低并发性,当多个线程竞争容器的锁时,吞吐量将严重减低. 另一个方面,并发容器是针对多个线程并发访问设计的.在java 5 ...
- JSP接口浅析
一.tree型关系 JSP页面继承了org.apache.jasper.runtime.HttpJspBase抽象类并实现了org.apache.jasper.runtime.JspSourceDep ...
- python 函数 参数 (难点传入dict list)
--使用参数组可以传值列表,字典:格式 #-*-coding:utf-8-*- def func5(x,*s,**gs): print(x) print(s) print(gs) print '*'* ...