类有数据属性和非数据属性,数据属性相当于C++中的类变量,非数据属性一般就是类的方法。类有很多特殊的数据属性,例如__dict__属性,它是一个字典,包含了所有类的属性及其值,__module__属性存储类所在的module名称字符串,__class__属性存储类的名称字符串。类也有很多特殊的方法,例如__new__,__delete__,含有很多可用于重载操作符的特殊方法,所谓的重载,实际上是继承类的方法覆盖了基类的同名方法,如果把派生类的方法删除,那么下次调用的就是基类的同名方法
def __init__(self,value):
self.val=value
def __get__(self,obj,typ=None):
print 'getting %s' % (obj)
return obj.__dict__[self.val]
def __set__(self,obj,value):
print 'setting %s=%s' % (obj,value)
obj.__dict__[self.val]=value
>>> class Test(object):
foo=desc('hangzhou')
>>> a=Test()
>>> a.foo #第一次访问foo属性,因为没有设置值导致失败
getting <__main__.Test object at 0xb56aabcc>
Traceback (most recent call last):
File "<pyshell#46>", line 1, in <module>
a.foo
File "<pyshell#40>", line 6, in __get__
return obj.__dict__[self.val]
KeyError: 'hangzhou'
>>> a.foo='sd'
setting <__main__.Test object at 0xb56aabcc>=sd
>>> a.foo
getting <__main__.Test object at 0xb56aabcc>
'sd'
>>> b.foo='jh'
>>> b.foo
'jh'
>>> a.foo #从这里可以看到在第二个实例b设置了foo属性之后,a实例的foo属性没有改变,这些都是由于通过描述符,把属性的值存储在各个实例的内部了
getting <__main__.Test object at 0xb56aabcc>
'sd'
>>>
def __init__(self,val):
self.__x=val
def get_x(self):
return self.__x
def set_x(self,val):
self.__x=val
x=property(get_x,set_x)
>>> m=MyProperty(10)
10
>>> m.x=100
>>> m.x
100
def __init__(self,getf=None,setf=None,delf=None):
self.getf=getf
self.setf=setf
self.delf=delf
def __get__(self,obj,typ=None):
return self.getf(obj)
def __set__(self,obj,val):
self.setf(obj,val)
>>> class MyTest(object):
def __init__(self,val):
self.__x=val
def get_x(self):
return self.__x
def set_x(self,val):
self.__x=val
x=MyProper(get_x,set_x)
>>> mt=MyTest(111)
>>> mt.x=222
>>> mt.x
222
>>> my=MyTest(444)
>>> my.x
444
>>> my.x=555
>>> my.x
555
>>> mt.x
222
这个版本中MyTest.__dict__中可以看到get_x和set_x方法,类用户甚至可以直接调用这两个函数进行赋值,这显然不符合我们的预期
隐藏属性访问方法
def __init__(self,val):
self._x=val
def x():
def fget(self):
return self._x
return locals()
x=property(**x())
>>> mc=MyClass(77)
>>> mc.x
77
>>> mc.x=100
Traceback (most recent call last):
File "<pyshell#150>", line 1, in <module>
mc.x=100
AttributeError: can't set attribute
def __init__(self,value):
self.__x=value
@property
def x(self):
return self.__x
@x.setter
def x(self,val):
self.__x=val
>>> n=NewProper(2)
>>> n.x
2
>>> n.x=10
>>> n.x
10
-
execfile
(
filename
[,
globals
[,
locals
]
]
)
-
This function is similar to the exec statement, but parses a file instead of a string. It is different from the import statement in that it does not use the module administration — it reads the file unconditionally and does not create a new module. [1]
The arguments are a file name and two optional dictionaries. The file is parsed and evaluated as a sequence of Python statements (similarly to a module) using the globals and locals dictionaries as global and local namespace. If provided, locals can be any mapping object. Remember that at module level, globals and locals are the same dictionary. If two separate objects are passed as globals and locals, the code will be executed as if it were embedded in a class definition.
Changed in version 2.4: formerly locals was required to be a dictionary.
If the locals dictionary is omitted it defaults to the globals dictionary. If both dictionaries are omitted, the expression is executed in the environment where execfile() is called. The return value is None.
-
可见exec函数,在提供了globals和locals两个参数之后,代码就像嵌入在类中一样,也就是说,在exec执行后,在class_dict中包含了__init__和blah这两个key
对type的解释如下:
在python文档的built-in functions中对type函数有如下描述:-
type
(
object
)
type
(
name,
bases,
dict
)
-
With one argument, return the type of an object. The return value is a type object. The isinstance() built-in function is recommended for testing the type of an object.
With three arguments, return a new type object. This is essentially a dynamic form of the class statement. The name string is the class name and becomes the __name__ attribute; the bases tuple itemizes the base classes and becomes the __bases__ attribute; and the dict dictionary is the namespace containing definitions for class body and becomes the __dict__ attribute. For example, the following two statements create identical type objects:
>>>>>> class X(object): ... a = 1 ... >>> X = type('X', (object,), dict(a=1))
-