免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2133 | 回复: 1
打印 上一主题 下一主题

在运行时创建描述符 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 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')
就是这样吧?!

论坛徽章:
5
巨蟹座
日期:2014-08-28 18:12:342015年迎新春徽章
日期:2015-03-04 10:01:4415-16赛季CBA联赛之江苏
日期:2016-04-28 09:43:3115-16赛季CBA联赛之吉林
日期:2016-06-22 10:34:4315-16赛季CBA联赛之山西
日期:2016-08-16 16:29:55
2 [报告]
发表于 2014-08-26 11:28 |只看该作者
你说的好多。。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP