# -*- coding: utf-8 -*-
"""
Created on Sat Dec 9 18:30:00 2017
@author: wyq
"""
"""
创建一对象,对其成员变量赋值。需要对赋值进行type检验。
实现 __get__、__set__、__delete__,则认为为descriptor类。
意味着:对变量(为对TypedProperty对象的一个reference)进行赋值运算时,调用相应的set函数
如果去掉(object),则不会报错,因为和descriptor不再有任何关系。
如果去掉__get__则print中只能打印出TypedProperty object 信息,不能得到具体值。
去掉__delete__如果不进行del不影响结果。
__init__将num与在set和get中的instance绑定。
这里直接使用了instance和cls来表示。
关于__get__:
1. Instance is the instance that the attribute was accessed through, or None when the attribute is accessed through the owner.
2. Owner is always the owner class.为Foo 或 TypedProperty 或 object 皆可。
3. The following methods only apply when an instance of the class containing the method (a so-called descriptor class) appears in an owner class (the descriptor must be in either the owner’s class dictionary or in the class dictionary for one of its parents).
4. This method should return the (computed) attribute value or raise an AttributeError exception.
将 c = TypedProperty("name",str)这样的语句放在class内与直接赋值,结果得到的c的type是不一样的。
由于type不同,__dict__内容根据所在class具体实现有所区别,但具体通过set、get来的key-value本质是没有区别的。
"""
import dis
class TypedProperty(object):
def __init__(self, name, type, default=None):
self.name = "_" + name
self.type = type
self.default = default if default else type()
def __get__(self, instance,cls):
return getattr(instance, self.name, self.default)
def __set__(self,instance,value):
if not isinstance(value,self.type):
raise TypeError("Must be a %s" % self.type)
setattr(instance,self.name,value)#相当于 instance.name = value
def __delete__(self,instance):
raise AttributeError("Can't delete attribute")
class Foo(object):
name = TypedProperty("name",str)
num = TypedProperty("num",int,42)
a= Foo()
print type(a.name)
print type(a.num)
a.name = 'wyq'
print a.name
a.num = 22
print type(a).__dict__['__dict__'].__get__(a, type(a))
print type(a).__dict__['num'].__get__(a, type(a))
print type(a).__dict__.keys()
# print a.num
# a.name= 12
#print a.num
#print dis.dis(TypedProperty)
#print dis.dis(Foo)
print '*****************************'
c = TypedProperty('name',str,'yq')#将instance和'w'绑定
print "type of c ",type(c)
#whatf = object()
#setattr(whatf,'w',None)
c.__set__(c,'k')#这里看出,a.name = 相当于调用了__set__
#c.__set__(c,2)
#print c.__get__(whatf,type(c))
print c.__get__(c,object)
print c.name,c.type,c.default
#print whatf == c
print type(c).__dict__.keys()
print type(c).__dict__['__dict__'].__get__(c, type(c))
print c._name
print c.default
print type(c._name)
print '*****************************'
print c.__getattribute__('__get__')
print c.__getattribute__('__dict__')
print a.__getattribute__('__dict__')
网友评论