十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
创新互联www.cdcxhl.cn八线动态BGP香港云服务器提供商,新人活动买多久送多久,划算不套路!
成都创新互联公司致力于互联网品牌建设与网络营销,包括做网站、成都做网站、SEO优化、网络推广、整站优化营销策划推广、电子商务、移动互联网营销等。成都创新互联公司为不同类型的客户提供良好的互联网应用定制及解决方案,成都创新互联公司核心团队10年专注互联网开发,积累了丰富的网站经验,为广大企业客户提供一站式企业网站建设服务,在网站建设行业内树立了良好口碑。这篇文章将为大家详细讲解有关Python有哪些属性和特性,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。
一、类属性、实例属性、私有属性与特性
类属性:类属性在__init__()外初始化,属于类所有,所有实例共享一个属性。
调用方法:类属性在内部用classname.类属性名调用,外部既可以用classname.类属性名又可以用instancename.类属性名来调用。
实例属性:实例属性属于各个实例所有,互不干扰。
私有属性:
1.单下划线_开头:只是告诉别人这是私有属性,外部依然可以访问更改。
2.双下划线__开头:外部不可通过instancename.propertyname来访问或者更改,实际将其转化为了_classname__propertyname。
特性:是用于管理实例属性的类属性。
特性用途:经常用于把公开的属性变成使用读值方法和设值方法管理的属性,且在不影响客户端代码的前提下实施业务规则。
注意:
不要对实例属性和类属性使用相同的名字。否则实例属性会遮盖类属性,发生难以发现的错误。
实例属性不会遮盖类特性,但类特性会遮盖实例属性。
这是因为obj.attr不会从实例obj开始寻找attr,而是从obj.__class__开始;而且仅当类中没有名为attr的特性时,Python才会在实例中寻找attr。
简言之,就遮盖层级而言,类特性>实例属性>类属性。
二、使用特性验证属性
使用特性可以验证实例属性的有效性,同时能够根据已知属性和属性之间的关系式调整其他属性,避免硬编码。
案例:假设某商店经营坚果、杂粮等多种有机食物,每位顾客的订单会包含店中的一系列商品,我们需要根据客户的订单计算出总价。
分析:我们不希望顾客订单的商品重量为非正数,需要借助@property装饰器实现值的获取与设置,从而验证实例属性的有效性。代码如下:
class LineItem(): def __init__(self,description,weight,price): self.description=description self.weight=weight self.price=price def subtotal(self): return self.weight*self.price @property#读值。 def weight(self): return self.__weight#真正的值存储在私有属性中。 @weight.setter def weight(self,value): if value >0: self.__weight=value#有效值存入私有属性中。 else: raise ValueError('Value must be > 0')#对于无效的值抛出ValueError。
Tips:当我们需要设置只读属性时,只使用@property,无需使用@func.setter。
原理解析:为了更好地理解@property装饰器的原理,我们写一版效果相同但没使用装饰器的代码。
class LineItem: def __init__(self, description, weight, price): self.description = description self.weight = weight self.price = price def subtotal(self): return self.weight * self.price def get_weight(self): #普通读值方法。 return self.__weight def set_weight(self, value): #普通设值方法。 if value > 0: self.__weight = value else: raise ValueError('value must be > 0') weight = property(get_weight, set_weight) #构建property对象,赋值给公开的类特性。
property 构造方法的完整签名:
property(fget=None, fset=None, fdel=None, doc=None)
三、特性工厂函数
抽象定义特性的方式有两种,一是使用特性工厂函数,二是使用描述符类。
下面我们用特性工厂函数来完成上文中提到的订单结算案例:
def quantity(storage_name): def qty_getter(instance): # instance指的是要把属性存储其中的LineItem实例。 return instance.__dict__[storage_name] # 引用闭包中的自由变量storage_name,值直接从instance.__dict__中获取,以便跳过特性,防止无限递归。 def qty_setter(instance, value): if value > 0: instance.__dict__[storage_name] = value # 同理存储,跳过特性。 else: raise ValueError('value must be > 0') return property(qty_getter, qty_setter) # 构建自定义特性对象并返回。 class LineItem: weight = quantity('weight') # 将自定义特性weight定义为类属性。 price = quantity('price') # 同上。 def __init__(self, description, weight, price): self.description = description self.weight = weight # 此处特性已经激活,可验证值的有效性。 self.price = price def subtotal(self): return self.weight * self.price # 此处利用特性获取实例中存储的值。
四、使用特性删除属性
class BlackKnight: def __init__(self): self.members = ['an arm', 'another arm', 'a leg', 'another leg'] self.phrases = ["'Tis but a scratch.", "It's just a flesh wound.", "I'm invincible!", "All right, we'll call it a draw."] @property def member(self): print('next member is:') return self.members[0] @member.deleter def member(self): text = 'BLACK KNIGHT (loses {})\n-- {}' print(text.format(self.members.pop(0), self.phrases.pop(0)))
删除属性只需在主程序中发出指令:del obj.attr
关于Python有哪些属性和特性就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。