1、字段 (普通字段,静态字段)
字段包括:普通字段和静态字段,他们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同
普通字段,存在对象中,通过对象访问
静态字段,存在类中,通过类名访问
静态字段的又一种用法,当需要访问多个方法中的普通字段,但是这些普通又都是相同的时候,我们就可以把它定义在类中,成为静态字段
class Person(object):
company = 'chuchujie' #静态字段
def __init__(self,name,age,sex):
self.name = name #普通字段
self.age = age
self.sex = sex
# 访问静态字段
print Person.company
#访问普通字段
P1 = Person('allen','25','male')
print P1.age
2、方法 (普通方法、类方法、静态方法)
方法包括: 普通方法、静态方法和类方法,三种方法在内存中都归属于类,区别在于调用方式不同
普通方法,通过对象触发,对象执行方法时自动把自己当作参数赋值给self(self是形式参数)
类方法,需要通过@classmethod装饰器装饰,同时方法的第一个参数是 “cls”
通过类触发,类对象执行时自动把自己当作参数传给cls
静态方法,没有默认参数(可以加任何参数)
class Person(object):
def __init__(self,name,age):
self.name = name
self.age = age
def f1(self):
print "f1"
@classmethod
def f2(cls): #类方法
print "f2"
@staticmethod
def f3(): #静态方法
print "f3"
#普通方法执行:
P1=Person()
P1.f1()
#类方法执行:
Person.f2()
#静态方法执行:
Person.f3()
总结:
普通方法,对象触发,至少一个参数(self),也可以加其他参数
类方法,类触发,只能有一个参数且只能是cls参数,不能为其他参数(如果你想是其他参数也是可以,但是告诉你这样做是不规范的,所以我们认为只能是cls参数,cls 表示class)
静态方法,可以加任意参数
对于调用:
普通方法: 对象调用
类方法 和 静态方法: 类调用
对于参数:
普通方法: 至少一个self
类方法: 只能一个参数,cls
静态方法: 任意参数
3、属性
普通属性:在类方法上面加上@property装饰器,就变成了属性
属性其实是普通方法的变种(python中,属性还用的特别少,因为功能还不够完善,对于其他语言,其他语言用的比较多了)
属性的定义有两种方式:
装饰器: 在方法上加上装饰器
静态字段: 在类中定义值为property对象的静态字段
实例:
对于主机列表页面,每次请求不可能把数据库中的所有内容都显示到页面上,而是通过分页的功能局部显示,所以在向数据库中请求数据时就要显示的指定获取从第m条到第n条的所有数据(即:limit m,n),这个分页的功能包括:
根据用户请求的当前页和总数据条数计算出 m 和 n
根据m 和 n 去数据库中请求数据
# ############### 定义 ###############
class Pager:
def __init__(self, current_page):
# 用户当前请求的页码(第一页、第二页...)
self.current_page = current_page
# 每页默认显示10条数据
self.per_items = 10
@property
def start(self):
val = (self.current_page - 1) * self.per_items
return val
@property
def end(self):
val = self.current_page * self.per_items
return val
# ############### 调用 ###############
p = Pager(1)
p.start 就是起始值,即:m
p.end 就是结束值,即:n
装饰器方式:在类的普通方法上应用@property装饰器
经典类中的属性只有一种访问方式,其对应被 @property 修饰的方法
class Persion:
def f1(self):
print "f1"
@property
def f2(self):
return "f4" 自动执行 @property 修饰的 price 方法,并获取方法的返回值
新式类,具有三种装饰器 分别被@property、@方法名.setter、@方法名.deleter 装饰
class Goods(object):
@property
def price(self):
print '@property'
@price.setter
def price(self, value):
print '@price.setter'
@price.deleter
def price(self):
print '@price.deleter'
# ############### 调用 ###############
obj = Goods()
obj.price # 自动执行 @property 修饰的 price 方法,并获取方法的返回值
obj.price = 123 # 自动执行 @price.setter 修饰的 price 方法,并将 123 赋值给方法的参数
del obj.price # 自动执行 @price.deleter 修饰的 price 方法
由于新式类中具有三种访问方式,我们可以根据他们几个属性的访问特点,分别将三个方法定义为对同一个属性:获取、修改、删除
class Goods(object):
def __init__(self):
# 原价
self.original_price = 100
# 折扣
self.discount = 0.8
@property
def price(self):
# 实际价格 = 原价 * 折扣
new_price = self.original_price * self.discount
return new_price
@price.setter
def price(self, value):
self.original_price = value
@price.deltter
def price(self, value):
del self.original_price
obj = Goods()
obj.price # 获取商品价格
obj.price = 200 # 修改商品原价
del obj.price # 删除商品原价
总结:
属性和方法唯一的区别就是:
属性在定义时需要在方法上面加上@property
在执行时不需要加括号
属性的目的,把一个方法伪造成一个字段,是一种假象
属性也是方法的一种,是对一个方法进行改造,进行修饰,访问时不需要再加括号了
属性只能有一个self参数