python 专题十七 类
2013-11-21 12:38
393 查看
字段
字段 (Field) 和 属性 (Property) 是不同的。• 实例字段存储在 instance.__dict__,代表单个对象实体的状态。
• 静态字段存储在 class.__dict__,为所有同类型实例共享。
• 必须通过类型和实例对象才能访问字段。
• 以双下划线开头的 class 和 instance 成员视为私有,会被重命名。(module 成员不变)
>>> class User(object): ... table = "t_user" ... def __init__(self, name, age): ... self.name = name ... self.age = age >>> u1 = User("user1", 20) # 实例字段存储在 instance.__dict__。 >>> u1.__dict__ {'age': 20, 'name': 'user1'} >>> u2 = User("user2", 30) # 每个实例的状态都是相互隔离的。 >>> u2.__dict__ {'age': 30, 'name': 'user2'} >>> for k, v in User.__dict__.items(): # 静态字段存储在 class.__dict__。 ... print "{0:12} = {1}".format(k, v) __module__ = __main__ __dict__ = <attribute '__dict__' of 'User' objects> __init__ = <function __init__ at 0x106eb4398> table = t_user
可以在任何时候添加实例字段,仅影响该实例名字空间,与其他同类型实例⽆无关。 >>> u1.x = 100 >>> u1.__dict__ {'x': 100, 'age': 20, 'name': 'user1'} >>> u2.__dict__ {'age': 30, 'name': 'user2'}
私有字段以双下划线开头,⽆无论是静态还是实例成员,都会被重命名: _<class>__<name>
>>> class User(object): ... __table = "t_user" ... ... def __init__(self, name, age): ... self.__name = name ... self.__age = age ... ... def __str__(self): ... return "{0}: {1}, {2}".format( ... self.__table, # 编码时⽆无需关⼼心重命名。 ... self.__name, ... self.__age) >>> u = User("tom", 20) >>> u.__dict__ # 可以看到私有实例字段被重命名了。 {'_User__name': 'tom', '_User__age': 20} >>> str(u) 't_user: tom, 20' >>> User.__dict__.keys() # 私有静态字段也被重命名。 ['_User__table', ...]某些时候,我们既想使⽤用私有字段,⼜又不想放弃外部访问权限。
• ⽤用重命名后的格式访问。
• 只⽤用⼀一个下划线,仅提醒,不重命名。
不必过于纠结 "权限" 这个词,从底层来看,本就没有私有⼀一说
属性
属性 (Property) 是由 getter、setter、deleter ⼏几个⽅方法构成的逻辑。属性可能直接返回字段值,也可能是动态逻辑运算的结果。
属性以装饰器或描述符实现,原理以后再说。实现规则很简单,也很好理解
>>> class User(object): ... @property ... def name(self): return self.__name # 注意⼏几个⽅方法是同名的。 ... ... @name.setter ... def name(self, value): self.__name = value ... ... @name.deleter ... def name(self): del self.__name >>> u = User() >>> u.name = "Tom" >>> u.__dict__ # 从 instance.__dict__ 可以看出属性和字段的差异。 {'_User__name': 'Tom'} >>> u.name # instance.__dict__ 中并没有 name,显然是 getter 起作⽤用了。 'Tom' >>> del u.name # 好吧,这是 deleter。 >>> u.__dict__ {} >>> for k, v in User.__dict__.items(): ... print "{0:12} = {1}".format(k, v) ... __module__ = __main__ __dict__ = <attribute '__dict__' of 'User' objects> name = <property object at 0x106ed6100>从 class.__dict__ 可以看出,⼏几个属性⽅方法最终变成了 property object。这也解释了⼏几个同名⽅方
法为何没有引发错误。既然如此,我们可以直接⽤用 property() 实现属性。
>>> class User(object): ... def get_name(self): return self.__name ... def set_name(self, value): self.__name = value ... def del_name(self): del self.__name ... name = property(get_name, set_name, del_name, "help...") >>> for k, v in User.__dict__.items(): ... print "{0:12} = {1}".format(k, v) __module__ = __main__ __dict__ = <attribute '__dict__' of 'User' objects> set_name = <function set_name at 0x106eb4b18> del_name = <function del_name at 0x106eb4b90> get_name = <function get_name at 0x106eb4aa0> name = <property object at 0x106ec8db8> >>> u = User() >>> u.name = "Tom" >>> u.__dict__ {'_User__name': 'Tom'} >>> u.name 'Tom' >>> del u.name >>> u.__dict__ {} 区别不⼤大,只是 class.__dict__ 中保留了⼏几个⽅方法。 属性⽅方法多半都很简单,⽤用 lambda 实现会更加简洁。鉴于 lambda 函数不能使⽤用赋值语句,故改 ⽤用 setattr。还得注意别⽤用会被重命名的私有字段名做参数。
>>> class User(object): ... def __init__(self, uid): ... self._uid = uid ... ... uid = property(lambda o: o._uid) # 只读属性。 ... ... name = property(lambda o: o._name, \ # 可读写属性。 ... lambda o, v: setattr(o, "_name", v)) >>> u = User(1) >>> u.uid 1 >>> u.uid = 100 AttributeError: can't set attribute >>> u.name = "Tom" >>> u.name 'Tom'
静态方法
>>> class User(object): ... def a(): pass ... ... @staticmethod ... def b(): pass ... ... @classmethod ... def c(cls): pass >>> User.a <unbound method User.a> >>> User.b <function b at 0x10c8ef320> >>> User.c <bound method type.c of <class '__main__.User'>>
相关文章推荐
- 向Python女神推荐这些年我追过的经典书籍
- python冒泡排序算法的实现代码
- python选择排序算法的实现代码
- Python的编码与解码
- python插入排序算法的实现代码
- Disable File System Redirector For Windows x64 (Python recipe)(转)
- Python正则表达式入门
- [Python下载CSDN博客]4. V3版本_使用正则表达式分析HTML(二)
- Python串口编程(转载)
- [Python下载CSDN博客]4. V3版本_使用正则表达式分析HTML(一)
- Python列表推导式的使用方法
- class类的定义(一) python
- 简明Python教程 10)编写 11)OO
- python 列表表达式和生成器表达式
- python模块 ---logging模块
- python模块 ---logging模块
- Python dictionary items() Method
- python os.path模块说明
- python中列表,元组,字符串如何互相转换
- python线程池