python 动态_关于Python的动态特性

动态解释

例1

定义三个功能类似的类:初始化名字,并有一个打印职业和名字的方法

2162901-20200922194753192-441985671.png

测试文件:

写一个测试方法who_am_i

2162901-20200922194816241-1908957652.png

输出结果:

2162901-20200922194831144-495618631.png

例2

Python提供了open()函数来打开一个磁盘文件,并返回 File 对象。File对象有一个read()方法可以读取文件内容:

例如,从文件读取内容并解析为JSON结果:

Python提供了open()函数来打开一个磁盘文件,并返回 File 对象。File对象有一个read()方法可以读取文件内容:

例如,从文件读取内容并解析为JSON结果:

importjson

f= open('/path/to/file.json', 'r')print json.load(f)

由于Python的动态特性,json.load()并不一定要从一个File对象读取内容。任何对象,只要有read()方法,就称为File-like Object,都可以传给json.load()。

请尝试编写一个File-like Object,把一个字符串 r'["Tim", "Bob", "Alice"]'包装成 File-like Object 并由 json.load() 解析。

importjsonclassStudents(object):defread(self):return r'["Tim", "Bob", "Alice"]'s=Students()printjson.load(s)

[u'Tim', u'Bob', u'Alice']

动态绑定属性

定义两个类做比较,一个定义了_slots_,另一个没有

classPlayer1(object):"""docstring for Player1"""

def __init__(self, uid, name, status = 0, level = 1):

self.uid=uid

self.name=name

self.status=status

self.level=levelclassPlayer2(object):"""docstring for Player2"""

__slots__ = ['uid', 'name', 'status', 'level']def __init__(self, uid, name, status = 0, level = 1):

self.uid=uid

self.name=name

self.status=status

self.level= level

ipython做测试,导入上面的两个类,并实例化

In [4]: from SlotsTest importPlayer1,Player2

In [5]: p1 = Player1('001','cici')

In [6]: p2 = Player2('002','coco')

先说下结论:第一个类比第二个要耗费内存

查看两个类属性的差集,看看第一个类多了什么

In [10]: set(dir(p1))-set(dir(p2))

Out[10]: {'__dict__', '__weakref__'}

!!!重点来了!!!

_dict_方法主要用于动态绑定属性,看下列测试结果

2162901-20200922195046245-802482088.png

2162901-20200922195100028-801818505.png

再比较一下两个对象的大小

importsys

In [27]: sys.getsizeof(p1)

Out[27]: 64In [28]: sys.getsizeof(p2)

Out[28]: 80In [29]: sys.getsizeof(p1.__dict__)

Out[29]: 1048

_slots_ = ['uid', 'name', 'status', 'level']

会屏蔽掉对象中的_dict_方法

屏蔽掉之后,对象将无法动态绑定属性

2162901-20200922195140117-479931213.png

动态绑定函数

我们在 class 中定义的实例方法其实也是属性,它实际上是一个函数对象:

classPerson(object):def __init__(self, name, score):

self.name=name

self.score=scoredefget_grade(self):return 'A'p1= Person('Bob', 90)printp1.get_grade#=> >

printp1.get_grade()#=> A

也就是说,p1.get_grade 返回的是一个函数对象,但这个函数是一个绑定到实例的函数,p1.get_grade() 才是方法调用。

因为方法也是一个属性,所以,它也可以动态地添加到实例上,只是需要用 types.MethodType() 把一个函数变为一个方法:

importtypesdeffn_get_grade(self):if self.score >= 80:return 'A'

if self.score >= 60:return 'B'

return 'C'

classPerson(object):def __init__(self, name, score):

self.name=name

self.score=score

p1= Person('Bob', 90)

p1.get_grade=types.MethodType(fn_get_grade, p1, Person)print p1.get_grade()

运行结果: A

p2 = Person('Alice', 65)print p2.get_grade()

运行结果: ERROR: AttributeError: 'Person' object has no attribute 'get_grade'

因为p2实例并没有绑定get_grade

动态构建类

Type函数

第一个参数是类的名字,第二个元组是父类,第三个是属性。

defattr(self):'''定义一个函数,并绑定到对象'''

return 1**2*3.14T= type('TypeClass', (object,), {'a':'Hello', 'attr':attr})

printT.aprint T.__dict__

print T.__name__

运行结果:Hello

dict_proxy({'a': 'Hello', '_module': '_main', 'attr': , '_dict': , '_weakref': , '_doc_': None})

TypeClass

t =T()printt.attr()print t.__dict__

运行结果:3.14

{}

printtype(T)print type(t)

运行结果:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值