之前是一知半解,现在懂了,记录一下
@classmethod
- 举例
class Date(object): def __init__(self,day=0,month=0,year=0) self.day = day self.month = month self.year = year @classmethod def from_string(cls,date_string): day,month,year = map(int,date_sting('-')) date1 = cls(day,month,year) return date1 # ---------- # 调用: date = Date.from_string('01-01-2019')
说明
上边利用 classmethod 来完成将字符串转为 Date 实例主要有这些优势:
1. 将字符串转化的过程放在类中, 并且能够重用;
2. 封装的较好, 符合面向对象思想;
3.classmethod 中的 cls 代表 Date, 它不是类的一个实例, 就是类对象本身, 如果我们派生了其他的子类, 它们也都能继承 from_string 方法.
@staticmethod
- 举例
class Date(object): def __init__(self,day=0,month=0,year=0) self.day = day self.month = month self.year = year @staticmethod def is_date_valid(date_string): day,month,year = map(int,date_sting('-')) return day <= 31 and month <= 12 and year <= 3999 # ---------- # 调用 date = Date.is_date_valid('01-01-2019')
说明:
staticmethod 可以像一个普通的方法被调用, 它与这个类有明确的相关性, 但是不需要访问这个类内部的属性或者方法.
@property
- 将类方法转变为只读属性
class Person(object): def __init__(self, first_name, last_name): """Constructor""" self.first_name = first_name self.last_name = last_name @property def full_name(self): """ Return the full name """ return "%s %s" % (self.first_name, self.last_name) # ------- # 调用 person = Person("Mike", "Driscoll") person.full_name # 输出-------- """ 'Mike Driscoll' """ person.first_name # 输出-------- """ 'Mike' """ person.full_name = "Jackalope" # 报错--------- """ Traceback (most recent call last): File "<string>", line 1, in <fragment> AttributeError: can't set attribute """ # full_name 方法已经变为一个属性了,并且只读,不能做修改 # 需要更改名称的话,只能更改初始化函数__init__() 中的 first_name 或者 last_name person.first_name = "Dan" person.full_name # 输出--------- """ 'Dan Driscoll' """
- 使用
property
取代setter
和getter
方法
这么一串代码
from decimal import Decimal class Fees(object): def __init__(self): """Constructor""" self._fee = None def get_fee(self): """ Return the current fee """ return self._fee def set_fee(self, value): """ Set the fee """ if isinstance(value, str): self._fee = Decimal(value) elif isinstance(value, Decimal): self._fee = value # -------- # 要使用这个类,我们必须要使用定义的 getter 和 setter 方法: f = Fees() f.set_fee("1") f.get_fee() # 输出: """ Decimal('1') """
如果想添加可以使用正常点符号访问的属性,而不破坏所有依赖于这段代码的应用程序,可以通过添加一个属性函数非常简单地改变它:
from decimal import Decimal class Fees(object): def __init__(self): """Constructor""" self._fee = None def get_fee(self): """ Return the current fee """ return self._fee def set_fee(self, value): """ Set the fee """ if isinstance(value, str): self._fee = Decimal(value) elif isinstance(value, Decimal): self._fee = value fee = property(get_fee, set_fee) # 我们在这段代码的末尾添加了一行。现在我们可以这样做: f = Fees() f.set_fee("1") f.see # 输出 """ Decimal('1') """ f.fee = "2" f.get_fee() # 输出 """ Decimal('2') """
正如所看到的,当我们以这种方式使用属性函数时,它允许 fee 属性设置并获取值本身而不破坏原有代码。让我们使用属性装饰器来重写这段代码,看看我们是否能得到一个允许设置的属性值:
from decimal import Decimal class Fees(object): def __init__(self): """Constructor""" self._fee = None @property def fee(self): """ The fee property - the getter """ return self._fee @fee.setter def fee(self, value): """ The setter of the fee property """ if isinstance(value, str): self._fee = Decimal(value) elif isinstance(value, Decimal): self._fee = value if __name__ == "__main__": f = Fees() """ 上面的代码演示了如何为 fee 属性创建一个 setter 方法。你可以用一个名为 @fee.setter 的装饰器装饰第二个方法名也为 fee 的方法来实现这个。当你如下所做时,setter 被调用: """ f = Fees() f.fee = "1" # 输出 """ Decimal('1') """
如果看属性函数的说明,它有 fget, fset, fdel 和 doc 几个参数。如果你想对属性使用 del 命令,你可以使用 @fee.deleter 创建另一个装饰器来装饰相同名字的函数从而实现删除的同样效果。
本文作者为 olei,转载请注明。