Python 中 property 的使用
2018-02-26 22:28
483 查看
在类似于 c++/java 这样的语言中,为了实现对类内部成员的封装。往往不会直接将一个变量作为公共成员暴露出来,而是会提供一对 get/set 函数来操作需要暴露的成员变量,这样不单提高了封装性, 减小了日后代码修改的影响范围,还可以在操作成员变量的时候提供一些必要的类似监控记录、校验等功能,是非常有用的。体现在代码中就是这样子:class Person {
public:
Person(int phone_num) : phone_num_(phone_num) { }
int get_phone_num() const { return phone_num_; }
int set_phone_num(int phone_num) { phone_num_ = phone_num; }
}
但是,如果你是一个 Python coder,那么恭喜你,强大的 Python 提供了一个很酷炫的解决方法,让你鱼与熊掌得兼。
这里的救世主就是内建的 property class。先看下面的 Python 代码class Person(object):
def __init__(self, phone_num):
self.phone_num = phone_num
def _get_phone_num(self):
print 'Get phone_num'
return self._phone_num;
def _set_phone_num(self, phone_num):
print 'Set phone_num to', phone_num
self._phone_num = phone_num
phone_num = property(
_get_phone_num, _set_phone_num,
doc='Example of usage of propery'
)
del _get_phone_num, _set_phone_num
有了 property,你对 phone_num 这样的成员变量的取用可以直接使用这样的语法:p = Person(110)
print p.phone_num
p.phone_num = 119 Python Cookbook 中并不鼓励对 class 中所有变量都使用这样的方法,认为这样是务必要的。书中推荐的做法是最开始就简单的使用原始属性,当确实发现需要进行封装或者加入一些校验的功能,再进行封装,拜 Python 语法所赐,这样的修改不会影响到任何客户端代码,不会带来任何额外成本,这真的是天上掉馅饼的美事啊!
下面附上 property class 的文档介绍
class property(object)
| property(fget=None, fset=None, fdel=None, doc=None) -> property attribute
|
| fget is a function to be used for getting an attribute value, and likewise
| fset is a function for setting, and fdel a function for del'ing, an
| attribute. Typical use is to define a managed attribute x:
| class C(object):
| def getx(self): return self._x
| def setx(self, value): self._x = value
| def delx(self): del self._x
| x = property(getx, setx, delx, "I'm the 'x' property.")
其实 property 本质上是一个描述器,而 Python 在查找到一个对象的属性时,如果这个属性时一个描述器, Python 就会用描述器的方法覆盖默认的属性控制方法,关于描述器的介绍,可以移步这里 Python 描述器介绍。
这就是酷酷的 Python property,是不是迫不及待想把它用在你的代码中了呢?
鉴于自身水平有限,文章中有难免有些错误,欢迎大家指出。也希望大家可以积极留言,与笔者一起讨论编程的那些事。
public:
Person(int phone_num) : phone_num_(phone_num) { }
int get_phone_num() const { return phone_num_; }
int set_phone_num(int phone_num) { phone_num_ = phone_num; }
}
Person p(110); p.set_phone_num(119); int num = p.get_phone_num();这样确实提供了良好的封装,而且为以后加入诸如变量校验这样的功能提供了很好的解决方法。但是却引入了大量重复劳作,如果有大量的变量需要供客户端取用,那么这样写接口,怕是要烦到敲烂键盘啊。如果你是一个 c++程序员(和笔者一样),那么对不起,让咱们一起抱头痛哭吧,就我所知并没有一个可在不损失封装性的前提下,大大减少代码量的解法。
但是,如果你是一个 Python coder,那么恭喜你,强大的 Python 提供了一个很酷炫的解决方法,让你鱼与熊掌得兼。
这里的救世主就是内建的 property class。先看下面的 Python 代码class Person(object):
def __init__(self, phone_num):
self.phone_num = phone_num
def _get_phone_num(self):
print 'Get phone_num'
return self._phone_num;
def _set_phone_num(self, phone_num):
print 'Set phone_num to', phone_num
self._phone_num = phone_num
phone_num = property(
_get_phone_num, _set_phone_num,
doc='Example of usage of propery'
)
del _get_phone_num, _set_phone_num
有了 property,你对 phone_num 这样的成员变量的取用可以直接使用这样的语法:p = Person(110)
print p.phone_num
p.phone_num = 119 Python Cookbook 中并不鼓励对 class 中所有变量都使用这样的方法,认为这样是务必要的。书中推荐的做法是最开始就简单的使用原始属性,当确实发现需要进行封装或者加入一些校验的功能,再进行封装,拜 Python 语法所赐,这样的修改不会影响到任何客户端代码,不会带来任何额外成本,这真的是天上掉馅饼的美事啊!
下面附上 property class 的文档介绍
class property(object)
| property(fget=None, fset=None, fdel=None, doc=None) -> property attribute
|
| fget is a function to be used for getting an attribute value, and likewise
| fset is a function for setting, and fdel a function for del'ing, an
| attribute. Typical use is to define a managed attribute x:
| class C(object):
| def getx(self): return self._x
| def setx(self, value): self._x = value
| def delx(self): del self._x
| x = property(getx, setx, delx, "I'm the 'x' property.")
其实 property 本质上是一个描述器,而 Python 在查找到一个对象的属性时,如果这个属性时一个描述器, Python 就会用描述器的方法覆盖默认的属性控制方法,关于描述器的介绍,可以移步这里 Python 描述器介绍。
这就是酷酷的 Python property,是不是迫不及待想把它用在你的代码中了呢?
鉴于自身水平有限,文章中有难免有些错误,欢迎大家指出。也希望大家可以积极留言,与笔者一起讨论编程的那些事。
相关文章推荐
- python中property的使用实例
- python使用@property @x.setter @x.deleter
- python的property语法的使用
- Python基础(6)- 类和对象(使用、继承、派生、组合、接口、多态、封装、property、staticmethod、classmethod、反射、slots、上下文管理协议、元类)
- python 进制运算 位运算 property的使用 通过property调用私有变量
- Python中使用property实现类的特性
- python 进制运算 位运算 property的使用 通过property调用私有变量
- [解决办法]Python中使用json.loads解码字符串时出错:ValueError: Expecting property name: line 1 column 2 (char 1)
- Python 使用Property
- [解决办法]Python中使用json.loads解码字符串时出错:ValueError: Expecting property name: line 1 column 2 (char 1)
- Python类中使用property() 函数 和@property 装饰符
- 【Python笔记】装饰器语法糖(@staticmethod/@classmethod/@property)原理剖析及使用场景说明
- python的property语法的使用
- python 旧类中使用property特性的方法
- python property方法的使用
- [解决办法]Python中使用json.loads解码字符串时出错:ValueError: Expecting property name: line 1 column 2 (char 1)
- property的使用Python3
- python property 简单使用
- python使用@property @x.setter @x.deleter
- Python3之封装property及使用