标签:
类的成员可以分为三类:字段、方法、属性
普通字段和静态字段,他们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同
字段的定义和使用
class Province: # 静态字段 country = ‘中国‘ def __init__(self,name): # 普通字段 self.name = name # 直接访问普通字段 obj = Province(‘北京‘) print obj.name # 直接访问静态字段 print Province.country
点睛:
1:谁来调用:
从上面可以看出普通字段需要通过对象来访问,静态字段通过类来调用。
2:存储的位置
通过类创建对象的时候,如果每个对象都具有相同的字段,那么就使用静态字段
普通方法、静态方法、类方法。三种方法在内存中都属于类,区别在于调用方式不同
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
class Foo: # 初始化类 def __init__( self ): pass # 定义普通方法,至少有一个self参数 def p( self ): print ‘普通方法‘ # 定义类方法,至少有一个cls参数 @classmethod def q( cls ): print ‘类方法‘ # 定义静态方法 @staticmethod def w(): print ‘静态方法‘ # 调用普通方法 a = Foo() ret = a.p() # print ret # 调用类方法 Foo.q() # 调用静态方法 Foo.w() |
点睛:
相同点:对于所有的方法而言,均属于类中,所以在内存中也之保存一份
不同点:方法调用者不同,调用方法时,自动传入的参数不同
1:属性的基本使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
class Foo: def func( self ): # print ‘func‘ return ‘方法调用的返回值‘ # 定义属性 @property def prop( self ): # print ‘prop‘ return ‘属性调用的返回值‘ # 调用方法 obj = Foo() ret = obj.func() print ret # 调用属性 ret1 = obj.prop print ret1 |
点睛:
方法:
obj = Foo()
ret = obj.func()
属性:
obj = Foo()
ret = obj.prop
属性存在的意义:访问属性时,可以制造出和访问字段完全相同的假象
实例:
对于主机列表页面,每次请求不可能把数据库中的所有内容都显示到页面上,而是通过分页的功能局部显示,所以在向数据库中请求数据时就要显示的指定获取从第M条到第N条的所有数据,这个分页功能包括:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
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( 2 ) print p.start print p.end # 结果: # 10 # 20 |
2:属性的两种定义方式
装饰器、静态字段
装饰器:在方法上应用装饰器
静态字段:在类中定义值为property对象的静态字段
装饰器方式:
经典类,具有一种@property装饰器
# 定义类 class Foo: @property def fun(self): return ‘caoxiaojian‘ # 调用属性 obj = Foo() ret = obj.fun print ret # 自动执行 @property修饰的fun方法,并获取方法的返回值
新式类,具有三种@property装饰器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
class Goods( object ): @property def price( self ): print ‘@property‘ @price .setter def price( self ,value): print ‘@price.setter‘ ,value @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方法 执行结果: @property @price .setter 123 @price .deleter |
注释:
经典类中的属性只用一种访问方式,其对应被@property修饰的方法
新式类中的属性有三种访问方式,并分别对应了三个被@property、@方法名.setter、@方法名.deleter修饰的方法
因为新式类有三种访问方式,我们可以根据他们几个属性的访问特点,分别将三个方法定义为同一个属性:获取、修改、删除
实例讲解:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
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 .deleter def price( self ,value): # 删除原始价格 del self .original_price # 调用 obj = Goods() # 获取商品价格 obj.price # 设置原始价格 obj.price = 3000 # 删除原始价格 del obj.price |
静态字段方式:
创建值为property对象的静态字段
当使用静态字段的方式创建属性时,经典类和新式类无区别
1
2
3
4
5
6
7
8
9
|
class Foo: def get_bar( self ): return ‘caoxiaojian‘ BAR = property (get_bar) obj = Foo() # 自动调用get_bar方法,并获取方法的返回值。 ret = obj.BAR print ret |
property的构造方法中有个四个参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
class Foo: def get_bar( self ): return ‘caoxiaojian‘ # 必须有两个参数 def set_bar( self ): return ‘set value‘ + value def del_bar( self ): return ‘caoxiaojian===2‘ BAR = property (get_bar, set_bar, del_bar, ‘description......‘ ) obj = Foo() print obj.BAR # 自动调用第一个参数中定义的方法:get_bar obj.BAR = "caogaotian" # 自动调用第二个参数中定义的方法:set_bar方法,将"caogaotian" 当作参数传入 print obj.BAR del obj.BAR # 自动调用第三个参数中定义的方法:del_bar print obj.del_bar() obj.BAR.__doc__ # 自动调用第三个参数中设置的值:‘description......‘ ‘‘‘ 结果输出: caoxiaojian caogaotian caoxiaojian===2 ‘‘‘ |
类成员的修饰符
两种形式:
定义的不同:
私有成员命名时,前面两个字符是下划线。(特殊成员除外,例如:__init__等)
class C: def __init__(self): self.name = ‘公有字段‘ self.__name = ‘私有字段‘
私有成员和公有成员的访问限制不同
静态字段
公有静态字段
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
class C: name = ‘公有静态字段‘ def func( self ): print C.name class D(C): def func_1( self ): print C.name # 直接使用类访问 C.name # 类内部访问 obj = C() obj.func() # 派生类内部访问 obj_1 = D() obj_1.func_1() ‘‘‘ 结果打印: 公有字段 公有字段 ‘‘‘ |
私有静态字段
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
class C: __name = ‘公有静态字段‘ def func( self ): print C.__name class D(C): def func_1( self ): print C.__name # 类中访问 # C.__name # 错误 # 类内部访问 obj = C() obj.func() # 派生类中访问 # obj_1 = D() # 错误 # obj_1.func_1() |
普通字段
公有普通字段
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
class C: def __init__( self ): self .foo = ‘公有字段‘ def func( self ): # 在类内部调用访问 print self .foo class D(C): def show( self ): # 在派生类中调用访问 print self .foo obj = C() # 通过对象访问 print type (obj.foo) print obj.foo print ‘===========‘ # 类的内部访问 obj.func() print ‘===========‘ obj_1 = D() # 在派生类中访问 obj_1.show() ‘‘‘ 结果打印: <type ‘str‘> 公有字段 =========== 公有字段 =========== 公有字段 ‘‘‘ |
私有普通字段
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
class C: def __init__( self ): self .__foo = ‘私有普通字段‘ def func( self ): # 类的内部调用访问 print self .__foo class D(C): def show( self ): # 在派生类中调用访问 print self .__foo obj = C() # obj.__foo # 通过对象访问:报错 obj.func() # 通过类内部访问 obj_1 = D() #obj_1.show() # 通过派生类调用访问: 报错 |
1:__doc__
表示类的描述信息
class C: """ 这是描述信息,你看什么看?? """ def func(self): pass print C.__doc__ # 输出:这是描述信息,你看什么看??
2:__module__和__class__
__module__:表示当前操作的对象在哪个模块
__class__: 表示当前操作的对象的类是哪一个
在tmp模块下面有test.py和test1.py
test.py
class C: def __init__(self): self.name = ‘caoxiaojian‘
test1.py
from test import C # 根据导入的C类创建对象 obj = C() # 获取对象中的模块名 print obj.__module__ # test # 获取对象中的类名 print obj.__class__ # test.C
3:__init__
构造方法,通过类创建对象时,自动触发执行
class C: def __init__(self,name): self.name = name self.age = 18 obj = C(‘caoxiaojian‘) # 自动执行类中的__init__方法 print obj.name
4:__call__
对象后面加括号,触发执行
点睛:
构造方法的执行是由创建对象触发的。即:对象名 = 类名()
__call__方法的执行由对象后面加括号触发的。即:对象()或者类名()()
class C: def __init__(self): pass def __call__(self, *args, **kwargs): print ‘__call__‘ obj = C() # 触发__init__ obj() # 触发__call__
5:__dict__
类或对象中的所有成员
点睛:
类的普通字段属于对象,类中的静态字段和方法等属于类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
class Province: country = ‘china‘ def __init__( self ,name,count): self .name = name self .count = count def func( self , * args, * * kwargs): print ‘func===func‘ # 获取类中的成员:静态字段和方法 print Province.__dict__ # {‘country‘: ‘china‘, ‘__module__‘: ‘__main__‘, ‘func‘: <function func at 0x021DA7F0>, ‘__init__‘: <function __init__ at 0x021DA870>, ‘__doc__‘: None} # 调用类创建obj对象 obj = Province( ‘shandong‘ , 100000 ) print obj.__dict__ # {‘count‘: 100000, ‘name‘: ‘shandong‘} # 调用类创建foo对象 foo = Province( ‘beijing‘ , 20000 ) print foo.__dict__ # {‘count‘: 20000, ‘name‘: ‘beijing‘} |
类的分类:
经典类和新式类
# 经典类 class func: def Foo(self): pass # 新式类 class func_new(object): def Foo_new(self): pass
点睛:
区别:就是在类的后面加个object
类的继承
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
# 新式类 class D( object ): # 经典类 #class D: def bar( self ): print ‘D.bar‘ class C(D): def bar( self ): print ‘C.bar‘ class B(D): pass class A(B,C): pass a = A() a.bar() ‘‘‘ 经典类:深度优先 D.bar 新式类:广度优先 C.bar ‘‘‘ |
点睛:
经典类:深度优化
新式类:广度优化
标签:
原文地址:http://www.cnblogs.com/kevingrace/p/5569987.html