Python 类 和 sub类 的 IsInstance()
Python IsInstance() for classes and subclasses
此代码来自 python 食谱第 3 版 类 章节第 8.13 节。该程序试图定义各种数据结构,但希望对允许分配给某些属性的值实施约束。
我正在 python 2.7 中使用 Pycharm IDE.
执行程序
# Base class. Uses a descriptor to set a value
class Descriptor(object):
def __init__(self, name=None, **opts):
self.name = name
for key, value in opts.items():
setattr(self, key, value)
def __set__(self, instance, value):
instance.__dict__[self.name] = value
# Descriptor for enforcing types
class Typed(Descriptor):
expected_type = type(None)
def __set__(self, instance, value):
if not isinstance(value, self.expected_type):
raise TypeError('expected ' + str(self.expected_type))
super(Typed,self).__set__(instance, value)
class Integer(Typed):
expected_type = int
class String(Typed):
expected_type = str
class MaxSized(Descriptor):
def __init__(self, name=None, **opts):
if 'size' not in opts:
raise TypeError('missing size option')
super(MaxSized,self).__init__(name, **opts)
def __set__(self, instance, value):
if len(value) >= self.size:
raise ValueError('size must be < ' + str(self.size))
super(MaxSized,self).__set__(instance, value)
class SizedString(String, MaxSized):
pass
# Class decorator to apply constraints
def check_attributes(**kwargs):
def decorate(cls):
for key, value in kwargs.items():
if isinstance(value, Descriptor):
value.name = key
setattr(cls, key, value)
else:
setattr(cls, key, value(key))
return cls
return decorate
# Example
@check_attributes(name=String,shares=Integer,place=SizedString('tester',size=8))
class Stock(object):
def __init__(self, stkname, stkqty,stkhq):
self.name = stkname
self.shares = stkqty
self.place = stkhq
使用以下初始化执行代码时,
s = Stock('ACME', 50,'hky')
print s.name # print ACME
print s.shares # prints 50
print s.place # prints hky
Condition:
当为@check_attributes place=SizedString('tester',size=8)调试下面的代码时,下面的if 条件为真,其中 name=String 和 shares=Integer ,其他条件为真。
if isinstance(value, Descriptor):
value.name = key
setattr(cls, key, value)
else:
setattr(cls, key, value(key))
Questions :
如果 SizedString 是 Descriptor 的实例(基于继承层次结构 - String、Typed、MaxSized、Descriptor),那么 String 和 Integer 也应该满足 If 条件,对吗?因为最后它也是 ( typed , Descriptor ) ?
的子类
- setattr(cls, key, value(key)) 中的 value(key) 是什么意思,看不懂 value(key ) 是什么意思?
抱歉上下文冗长,但希望尽可能清楚。
If SizedString is an instance of Descriptor ( based on Inheritance hierarchy- String , Typed , MaxSized, Descriptor ), then String and Integer also should satisfy the If condition right ? because at the end it is also the subclass of ( typed , Descriptor ) ?
我们必须仔细查看传递给 check_attributes
函数的内容。仔细看看 name
和 share
关键字参数的值是什么:
@check_attributes(name=String,shares=Integer,place=SizedString('tester',size=8))
注意到 String
和 Integer
class 名称后缺少括号了吗?这意味着 String
和 Integer
class 对象本身 被传递到 check_attributes
,而不是任何一个 [=45= 的实例].由于 String
class 对象和 Integer
class 对象不是 Descriptor
的子 class,isinstance(value, Descriptor)
失败.
What is value(key) in setattr(cls, key, value(key)) means , cant understand what is value(key ) means ?
想一想。由于 value
具有传递给 check_attributes
的任何关键字参数的值,并且该值不是 Descriptor
class 的实例,因此 value
必须是引用 class 对象。 (如果你不明白这是为什么,请参考我对你第一个问题的回答)。所以调用 value(key)
是创建一些 class 的实例,并将 key
值作为构造函数参数传递。
此代码来自 python 食谱第 3 版 类 章节第 8.13 节。该程序试图定义各种数据结构,但希望对允许分配给某些属性的值实施约束。 我正在 python 2.7 中使用 Pycharm IDE.
执行程序# Base class. Uses a descriptor to set a value
class Descriptor(object):
def __init__(self, name=None, **opts):
self.name = name
for key, value in opts.items():
setattr(self, key, value)
def __set__(self, instance, value):
instance.__dict__[self.name] = value
# Descriptor for enforcing types
class Typed(Descriptor):
expected_type = type(None)
def __set__(self, instance, value):
if not isinstance(value, self.expected_type):
raise TypeError('expected ' + str(self.expected_type))
super(Typed,self).__set__(instance, value)
class Integer(Typed):
expected_type = int
class String(Typed):
expected_type = str
class MaxSized(Descriptor):
def __init__(self, name=None, **opts):
if 'size' not in opts:
raise TypeError('missing size option')
super(MaxSized,self).__init__(name, **opts)
def __set__(self, instance, value):
if len(value) >= self.size:
raise ValueError('size must be < ' + str(self.size))
super(MaxSized,self).__set__(instance, value)
class SizedString(String, MaxSized):
pass
# Class decorator to apply constraints
def check_attributes(**kwargs):
def decorate(cls):
for key, value in kwargs.items():
if isinstance(value, Descriptor):
value.name = key
setattr(cls, key, value)
else:
setattr(cls, key, value(key))
return cls
return decorate
# Example
@check_attributes(name=String,shares=Integer,place=SizedString('tester',size=8))
class Stock(object):
def __init__(self, stkname, stkqty,stkhq):
self.name = stkname
self.shares = stkqty
self.place = stkhq
使用以下初始化执行代码时,
s = Stock('ACME', 50,'hky')
print s.name # print ACME
print s.shares # prints 50
print s.place # prints hky
Condition:
当为@check_attributes place=SizedString('tester',size=8)调试下面的代码时,下面的if 条件为真,其中 name=String 和 shares=Integer ,其他条件为真。
if isinstance(value, Descriptor):
value.name = key
setattr(cls, key, value)
else:
setattr(cls, key, value(key))
Questions :
如果 SizedString 是 Descriptor 的实例(基于继承层次结构 - String、Typed、MaxSized、Descriptor),那么 String 和 Integer 也应该满足 If 条件,对吗?因为最后它也是 ( typed , Descriptor ) ?
的子类- setattr(cls, key, value(key)) 中的 value(key) 是什么意思,看不懂 value(key ) 是什么意思?
抱歉上下文冗长,但希望尽可能清楚。
If SizedString is an instance of Descriptor ( based on Inheritance hierarchy- String , Typed , MaxSized, Descriptor ), then String and Integer also should satisfy the If condition right ? because at the end it is also the subclass of ( typed , Descriptor ) ?
我们必须仔细查看传递给
check_attributes
函数的内容。仔细看看name
和share
关键字参数的值是什么:@check_attributes(name=String,shares=Integer,place=SizedString('tester',size=8))
注意到
String
和Integer
class 名称后缺少括号了吗?这意味着String
和Integer
class 对象本身 被传递到check_attributes
,而不是任何一个 [=45= 的实例].由于String
class 对象和Integer
class 对象不是Descriptor
的子 class,isinstance(value, Descriptor)
失败.What is value(key) in setattr(cls, key, value(key)) means , cant understand what is value(key ) means ?
想一想。由于
value
具有传递给check_attributes
的任何关键字参数的值,并且该值不是Descriptor
class 的实例,因此value
必须是引用 class 对象。 (如果你不明白这是为什么,请参考我对你第一个问题的回答)。所以调用value(key)
是创建一些 class 的实例,并将key
值作为构造函数参数传递。