luofeiyu_cu 发表于 2014-08-23 20:23

在运行时创建描述符

本帖最后由 luofeiyu_cu 于 2014-08-23 21:28 编辑

两个问题:
1.与正题无关
我的源文件在vim下格式好好的,复制到这里就变了,如何让它不变化?
class Person(object):
    def addProperty(self, attribute):
      # create local setter and getter with a particular attribute name
      getter = lambda self: self._getProperty(attribute)
      setter = lambda self, value: self._setProperty(attribute, value)
      # construct property attribute and add it to the class
      setattr(self.__class__, attribute, property(fget=getter,fset=setter,doc="Auto-generated method"))
    def _setProperty(self, attribute, value):
      setattr(self, '_' + attribute, value.title())   
    def _getProperty(self, attribute):
      return getattr(self, '_' + attribute)

2.正题
源代码
class Person(object):
      def addProperty(self, attribute):
      # create local setter and getter with a particular attribute name
         getter = lambda self: self._getProperty(attribute)
         setter = lambda self, value: self._setProperty(attribute, value)
      # construct property attribute and add it to the class
         setattr(self.__class__, attribute, property(fget=getter,fset=setter,doc="Auto-generated method"))
      def _setProperty(self, attribute, value):
         setattr(self, '_' + attribute, value.title())   
      def _getProperty(self, attribute):
         return getattr(self, '_' + attribute)

>>> user = Person()
>>> user.addProperty('name')
>>> user.addProperty('phone')
>>> user.name = 'john smith'
>>> user.name
'John Smith'
>>> user.__dict__
{'_name': 'John Smith'}

它会在运行的时候,动态产生属性和属性的值。

请问,究竟是如何运行的?

1.user = Person()
实例化的时候,没有__init__,没有发生任何行为。
2.user.addProperty('name')
1)getter=lambda self: self._getProperty(attribute) 运行了 ,产生一个函数_getProperty("name")
2)setter = lambda self, value: self._setProperty(attribute, value)这个lambda没有任何动作吧
3) setattr(self.__class__, attribute, property(fget=getter,fset=setter,doc="Auto-generated method"))

setattr(object, name, value)

Set a named attribute on an object; setattr(x, 'y', v) is equivalent to
``x.y = v''.

这里name="name" , value =property(fget=getter,fset=setter,doc="Auto-generated method")

就是self.__class__.name = property(fget=getter,fset=setter,doc="Auto-generated method")

property内建函数为self.__class__.name 创建了一个数据描述符。


3.user.name = 'john smith'
触发数据描述符的setter方法,   调用setter = lambda self, value: self._setProperty(attribute, value) 函数,
此时value('john smith')被传入,并调用_setProperty(attribute, value) 方法,ok.

4.user.name 触发getter方法, 调用getter = lambda self: self._getProperty(attribute) ,
name被赋值给attribute,并调用_getProperty(self, attribute)获得输出。

基本分析清楚了,只有一点不太确认,
user.addProperty('name') 的时候    setter = lambda self, value: self._setProperty(attribute, value)这个lambda函数没有运行吧?
是这样理解吧,它变成    setter = lambda self, value: self._setProperty('name', value)
当user.name='john smith'的时候,触发了它,将value ('john smith')带入
setter = lambda self, value: self._setProperty('name', value)变成了
setter = lambda self, 'john smith': self._setProperty('name', 'john smith')
就是这样吧?!

Linux_manne 发表于 2014-08-26 11:28

你说的好多。。。 :sleepy:
页: [1]
查看完整版本: 在运行时创建描述符