绑定与非绑定方法及反射,isinstance和issubclass内置函数
绑定方法与非绑定方法
1.绑定方法
绑定方法:绑定给谁就应该由谁来调用,谁来调用就会将谁当做第一个参数传入
绑定给对象的方法:
类中定义的函数默认就是绑定给对象的
绑定给类的方法:
为类中定义的函数加上一个装饰器classmethod
2.非绑定方法(staticmethod)
非绑定方法: 既不与类绑定,又不与对象绑定,意味着对象和类都可以来调用,无 论谁来调用都是一个普通的函数,没有自动传值的效果;为类中定义的函数加上一个装 饰器staticmethod。
示例
class Foo:
def f1(self):
print(self)
@classmethod
def f2(cls):
print(cls) # <class '__main__.Foo'>
@staticmethod
def f3(x,y):
print('f3',x+y)
obj=Foo()
print(Foo.f1) # 就是一个普通函数 <function Foo.f1 at 0x0000000002965620>
print(obj.f1) # 对象绑定方法 <bound method Foo.f1 of <__main__.Foo object at 0x0000000009F83C88>>
obj.f1() # <__main__.Foo object at 0x0000000009F83C88>
print(Foo.f2) # 类绑定方法 <bound method Foo.f2 of <class '__main__.Foo'>>
Foo.f2()
print(obj.f2) # <bound method Foo.f2 of <class '__main__.Foo'>>
obj.f2()
print(Foo.f3) # <function Foo.f3 at 0x0000000009FF4F28>
print(obj.f3) # <function Foo.f3 at 0x0000000009FF4F28>
Foo.f3(1,2) # f3 3
obj.f3(3,4) # f3 7
应用
# settings.py
ip='127.0.o.1'
port='3306'
# 当前文件
import settings
class MySql:
def __init__(self, ip, port):
self.id = self.create_id()
self.ip = ip
self.port = port
def tell_info(self):
print('<id:%s ip:%s port:%s>' % (self.id, self.ip, self.port))
@classmethod
def from_conf(cls):
return cls(settings.IP, settings.PORT)
@staticmethod
def create_id():
import uuid
return uuid.uuid4()
# obj1=MySql('1.1.1.1',3306)
# obj1.tell_info() # <id:9b13ad59-10e0-4b65-af15-b5d7d97034e1 ip:1.1.1.1 port:3306>
obj2 = MySql.from_conf()
obj2.tell_info()
isinstance和issubclass 内置函数
1.isinstance
判断一个对象是否是一个类的实例。
isinstance(参数1,参数2):用于判断参数1是否是参数2的一个实例。
isinstance(对象,类)
2.issubclass
判断一个类是否是另一个类的子类
issubclass(参数1, 参数2):用与判断参数1是否是参数2的子类。
print(isinstance(10,int)) # True
class Foo:
pass
class Goo(Foo):
pass
foo_obj = Foo()
print(isinstance(foo_obj, Foo)) # True
print(isinstance(foo_obj, Goo)) # False
print(issubclass(Goo, Foo)) # True
foo_obj = Goo()
print(isinstance(foo_obj, Goo)) # True
print(isinstance(foo_obj, Foo)) # True
反射(面向对象高阶)
反射定义
反射就是反省,自省的意思,指的是一个对象应该具备,可以检测,修改,增加自身属性的能力 ;通过字符串的形式操作对象相关的属性。
4个可以实现反省的函数(内置函数)
hasattr (参数1(对象),参数2) 判断某个对象是否存在某个属性;
getattr(参数1(对象),参数2,参数3) 从参数1中取出某个属性,第三个参数是默认 值,当属性不存在时,没有第三个参数报错,有的话,返回第三个参数;
setattr(参数1(对象),参数2(属性),参数3(属性值)),为对象添加新的属性
delattr(参数1(对象),参数2(属性名)):从对象中删除属性;
class People:
country = 'China'
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex
p = People('tank', 17, 'male')
# 普通方式
print('name' in p.__dict__) # True
print('country' in People.__dict__) # True
print('country2' in People.__dict__) # False
# hasattr
print(hasattr(p, 'name')) # True
print(hasattr(People, 'country')) # True
# 普通方式
print(p.__dict__.get('name')) # tank
print(p.__dict__.get('level', '9')) # 9
# getattr
print(getattr(p, 'name', 'jason_sb')) # tank
print(getattr(p, 'name1', 'jason_sb')) # jason_sb
print(getattr(People, 'country2', 'China'))
# setattr
# 普通
p.level = 10
print(p.__dict__) # {'name': 'tank', 'age': 17, 'sex': 'male', 'level': 10}
# 反射
setattr(p, 'sal', '3.0')
print(hasattr(p, 'sal')) # True
print(p.__dict__) # {'name': 'tank', 'age': 17, 'sex': 'male', 'level': 10, 'sal': '3.0'}
# delattr
# 普通
del p.level
print(hasattr(p, 'level')) # False
# 反射
delattr(p, 'sal')
print(hasattr(p, 'sal')) # False
反射小练习
class Movie:
def input_cmd(self):
print('输入命令:')
while True:
cmd = input('请输入执行的方法名:').strip()
# 若用户输入的cmd命令是当前对象的属性
if hasattr(self, cmd):
# if cmd in self.__class__.__dict__:
method = getattr(self, cmd)
method()
else:
print('命令错误,请重新输入!')
def upload(self):
print('电影开始上传...')
def download(self):
print('电影开始下载...')
movie_obj = Movie()
movie_obj.input_cmd()
反射使用场景
反射其实就是对属性的增删改查,但是如果直接使用内置的__dict__来操作,语法繁琐,不好理解
另外一个最主要的问题是,如果对象不是我自己写的是另一方提供的,我就必须判断这个对 象是否满足要求,是否是我需要的属性和方法
应用:一般用在框架设计,反射被称为框架的基石;因为框架的设计者,不可能提前知道 你的对象到底是怎么设计的,所以你提供给框架的对象,必须通过判断验证之后才能正常 使用,判断验证就是反射要做的事情,当然通过__dict__也是可以实现的, 其实这些方法也就是对 __dict__的操作进行了封装
反射动态导入示例
'''
需求:要实现一个用于处理用户的终端指令的小框架
框架就是已经实现了最基础的构架,就是所有项目都一样的部分
'''
# libs.plugins.py # libs文件夹下的plugins文件
# 插件部分
class WinCMD:
def cd(self):
print("wincmd 切换目录....")
def delete(self):
print("wincmd 要不要删库跑路?")
def dir(self):
print("wincmd 列出所有文件....")
class LinuxCMD:
def cd(self):
print("Linuxcmd 切换目录....")
def rm(self):
print("Linuxcmd 要不要删库跑路?")
def ls(self):
print("Linuxcmd 列出所有文件....")
# settings.py 文件
'''作为框架的配置文件'''
# 作为框架使用者,在配置文件中指定你配合框架的类是哪个框架的使用者提供一个配置文件,要求对方将类的信息写入配置文件,然后框架自己去加载需要的模块
class_path = 'libs.plugins.WinCMD' # libs是plugins.py文件所在的文件夹
# myframework.py 文件
#框架的设计者
import importlib
import settings
# 框架已经实现的部分
def run(plugin):
while True:
cmd = input("请输入指令:")
if cmd == "exit":
break
# 因为无法确定框架使用者是否传入正确的对象所以需要使用反射来检测
# 判断对象是否具备处理这个指令的方法
if hasattr(plugin,cmd):
# 取出对应方法方法
func = getattr(plugin,cmd)
func() # 执行方法处理指令
else:
print("该指令不受支持...")
print("see you la la!")
# 创建一个插件对象 调用框架来使用它
# wincmd = plugins.WinCMD()
# 框架之外的部分就有自定义对象来完成
# 框架得根据配置文件拿到需要的类
path = settings.CLASS_PATH
# 从配置中单独拿出来 模块路径和 类名称
module_path,class_name = path.rsplit(".",1) # libs.plugins,WinCMD
#拿到模块
mk = importlib.import_module(module_path)
# 拿到类
cls = getattr(mk,class_name)
# 实例化对象
obj = cls()
#调用框架
run(obj)
绑定与非绑定方法及反射,isinstance和issubclass内置函数的更多相关文章
- python基础之 反射,md5加密 以及isinstance, type, issubclass内置方法的运用
内容梗概: 1. isinstance, type, issubclass 2. 区分函数和方法 3. 反射(重点) 4. md5加密 1. isinstance, type, issubclass1 ...
- Python学习日记(二十七) 反射和几个内置函数
isinstance() 判断isinstance(obj,cls)中obj是否是cls类的对象 class Person: def __init__(self,name): self.name = ...
- 面向对象之反射 与__str__等内置函数
一 反射 1.面向对象中的反射:通过字符串的形式操作对象的相关属性,python中一切事物都是属性(都可以使用反射) 四个可以实现自省<反射>的函数:hasattr / getattr ...
- 字典内置函数&方法
字典内置函数&方法 Python字典包含了以下内置函数:高佣联盟 www.cgewang.com 序号 函数及描述 1 cmp(dict1, dict2)比较两个字典元素. 2 len(dic ...
- python面向编程;类的绑定与非绑定方法、反射、内置方法
一.类的绑定与非绑定方法 ''' 类中定义函数分为了两大类: 1. 绑定方法 特殊之处: 绑定给谁就应该由谁来调用,谁来调用就会将谁当做第一个参数自动传入 绑定给对象的方法: 在类中定义函数没有被任何 ...
- python3全栈开发-内置函数补充,反射,元类,__str__,__del__,exec,type,__call__方法
一.内置函数补充 1.isinstance(obj,cls)检查是否obj是否是类 cls 的对象 class Foo(object): pass obj = Foo() print(isinstan ...
- javascript内置函数提供的显式绑定
内置函数提供的显式绑定 最近在开发中遇到使用arr.map(module.fun) 这样的写法时(在一个模块调用了另外一个模块的方法), 造成了函数中this丢失的问题, 显示为undefined, ...
- python---issubclass/type/isinstance/ 反射(内置函数getattr/delattr...)
# 一 python面向对象-内置函数(issubclass(), type(), isinstance()) # issubclass 判断xxxx类是否是xxxx类的子类 class egg: p ...
- day28 面向对象:反射,内置函数,类的内置方法
面向对象进阶博客地址链接: http://www.cnblogs.com/Eva-J/articles/7351812.html 复习昨日内容: # 包 # 开发规范 # # hashlib # 登录 ...
随机推荐
- 简单的利用nginx部署前端项目
网上有很多教程写的一大堆东西,新手可能会有点看不懂,现在我写这篇文章是为了更好的帮助新手,如何将自己的前端项目部署到自己的服务器上. 首先我们必须要有一台自己的ubuntu服务器,如果没有可以去阿里云 ...
- String和ByteBuffer互转
String 转换 ByteBuffer: public static ByteBuffer getByteBuffer(String str) { return ByteBuffer.wrap(st ...
- 菜鸟系列Fabric——Fabric 1.2 多机部署(3)
多机部署fabric kafka共识 1. 角色分配 主机1 主机 2 Org1 peer0 1 Org2 peer 0 1 Orderer 0 1 Orderer 2 kafka 0 1 kafka ...
- spring5源码分析系列(一)——spring5框架模块
spring总共大约20个模块,这些模块被整合在核心容器(Core Container).AOP和设备支持.数据访问及集成.Web.报文发送.Test 6个模块集合. 组成Spring框架的每个模块集 ...
- 设计模式:职责链模式(Chain of Responsibility)
去年参加校招要到长沙来,这个对于我来说不是特别喜欢(但又必须的来,谁叫咱不是985.211的娃呢),但是对于某些人来说就是福音了.大四还有课,而且学校抓的比较严,所以对于那些想翘课的人来说这个是最好不 ...
- Luogu P4878 [USACO05DEC]布局
题目 差分约束模板. 注意判负环需要建一个超级源点到每个点连一条\(0\)的边.因为\(1\)不一定能到达所有的点. #include<bits/stdc++.h> #define pi ...
- Hadoop单机模式/伪分布式模式/完全分布式模式
一.Hadoop的三种运行模式(启动模式) 一.单机(非分布式)模式 这种模式在一台单机上运行,没有分布式文件系统,而是直接读写本地操作系统的文件系统. 默认情况下,Hadoop即处于该模式,用于开发 ...
- Linux-1.1root初始密码设置,切换root用户
Ubuntu安装好后,root密码需要自己设置 root初始密码设置 sudo passwd root 权限不够时,切换root su 回车后输入密码 exit 退出登录的账户
- HTML5-placeholder属性
HTML 5<input> placeholder属性 placeholder属性提供可描述输入字段预期值的提示信息(hint). 该提示会在输入字段为空时显示,并会在字段获得焦点时消失. ...
- SQL学习(一)之简介
什么是 SQL? SQL 指结构化查询语言(Structured Query Language) SQL 使我们有能力访问数据库 SQL 是一种 ANSI 的标准计算机语言 SQL 能做什么? SQL ...