面向对象——细节
Posted ykgo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面向对象——细节相关的知识,希望对你有一定的参考价值。
类的细节
1.property
方法在类中就是一种行为,行为是一个动词,可有的时候,我们想让方法这个‘动词‘变成‘名词‘,提供这样的机制。来达到实际所需的效果。property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值。
例子一: 特性的使用
class People: def __init__(self, name, weight, height): self.name = name self.weight = weight self.height = height @property # 通过这个装饰器,我们让方法立即变身 def bim(self): return self.weight / (self.height ** 2) p = People(‘yk‘, 55, 1.65) print(p.bim) # 20.202020202020204 # 咦,不是应该是 p.bim()嘛。别忘了,我们在方法的前面加了‘@property‘。成功包装成一个名词‘属性‘,有时候你确实需要这种效果。
注意:
此时的特性bim不能被赋值
p.bim=23 # 为特性bim赋值
# AttributeError: can‘t set attribute
为什么要用property
将一个类的函数定义成特性以后,对象再去使用的时候obj.name,根本无法察觉自己的name是执行了一个函数然后计算出来的,这种特性的使用方式遵循了统一访问的原则。
例子二:我们真的不能通过property设置值吗?
class Foo: def __init__(self,val): self.__NAME=val #将所有的数据属性都隐藏起来 @property def name(self): return self.__NAME #obj.name访问的是self.__NAME(这也是真实值的存放位置) @name.setter # 可以用这个装饰器修改 def name(self,value): if not isinstance(value,str): #在设定值之前进行类型检查 raise TypeError(‘%s must be str‘ %value) self.__NAME=value #通过类型检查后,将值value存放到真实的位置self.__NAME @name.deleter # 删除时会触发 def name(self): raise TypeError(‘Can not delete‘) f=Foo(‘yk‘) print(f.name) # yk # f.name=10 #抛出异常‘TypeError: 10 must be str‘ f.name = ‘小明‘ print(f.name) # 小明,修改成功 del f.name #抛出异常‘TypeError: Can not delete‘
2.绑定方法和非绑定方法
一、绑定方法(绑定给谁,谁来调用就自动将它本身当作第一个参数传入):
1.绑定到对象的方法:没有被任何装饰器装饰的方法。
对象.boud_method(), 自动将对象当作第一个参数传入
(属于类的函数,类可以调用,但是必须按照函数的规则来,不会自动传值)
2.绑定到类的方法,用 @classmethod 装饰器修饰的方法
类名.boud_method(), 自动将类当作第一个参数传入
(其实对象也可调用,但仍将类当作第一个参数传入)
class Foo: def __init__(self, name): self.name = name def myself(self): print("我是 %s" % self.name) @classmethod # 类方法 def clss(cls): print("我是 类方法") f = Foo(‘yk‘) print(f.myself) # <bound method Foo.myself of <__main__.Foo object at 0x000002B28FB59A90>> f.myself() # 我是 yk print(Foo.clss) # <bound method Foo.clss of <class ‘__main__.Foo‘>> Foo.clss() # 我是 类方法 f.clss() #对象也可以调用,但是默认传的第一个参数仍然是类
二、非绑定方法
不与类或对象绑定,类和对象都可以调用,但是不会自动传值。就是一个普通工具而已
注意:
与绑定到对象方法区分开,在类中直接定义的函数,没有被任何装饰器装饰的,都是绑定到对象的方法,可不是普通函数,对象调用该方法会自动传值,而staticmethod装饰的方法,不管谁来调用,都没有自动传值一说
class Foo: def __init__(self, name): self.name = name @staticmethod def stat(s1, s2): print(s1+s2) f = Foo(‘yk‘) print(f.stat) # <function Foo.stat at 0x000001F59F6B5B70> 它就是一个普通的函数而已 f.stat("hello ","yk") # hello yk
3.反射
反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。
python面向对象中的反射:通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)
# 自省方法 class Foo: def __init__(self, name): self.name = name def test(self): print("test.....") f = Foo("yk") # 检测是否含有某属性 print(hasattr(f, ‘name‘)) # True print(hasattr(f, ‘age‘)) # False # 获取属性,如果没有就返回第三个参数设置的值 print(getattr(f, ‘name‘, "没有这个属性")) # yk # 设置属性 setattr(f, ‘age‘, 18) print(f.age) # 18 # 删除属性 delattr(f, ‘name‘) print(hasattr(f, ‘name‘)) # False
# 我们可以模拟一个把控制权暂时交给用户的实现 class Demo: def __init__(self): self.cmd() def cmd(self): while True: # 用户输入一个已知命令 cmd = input("cmd=>>>").strip() # 如果有这个属性 if hasattr(self, cmd): # 获取该属性 arg = getattr(self, cmd) # 执行相应命令 arg() else: break def get(self): print("get.....") def put(self): print("put.....") d = Demo() # cmd=>>>get # get..... # cmd=>>>put # put..... # cmd=>>>p
以上是关于面向对象——细节的主要内容,如果未能解决你的问题,请参考以下文章
Android 逆向使用 Python 解析 ELF 文件 ( Capstone 反汇编 ELF 文件中的机器码数据 | 创建反汇编解析器实例对象 | 设置汇编解析器显示细节 )(代码片段