Python进阶-面向对象

简介:

 

 

类的成员

类的成员可以分为三类:字段、方法、属性

一:字段:

普通字段和静态字段,他们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同

  • 普通字段属于对象
  • 静态字段属于类

字段的定义和使用

复制代码
复制代码
class Province:
    # 静态字段
    country = '中国'
    def __init__(self,name):
        # 普通字段
        self.name = name
# 直接访问普通字段
obj = Province('北京')
print obj.name

# 直接访问静态字段
print Province.country
复制代码
复制代码

点睛:

1:谁来调用:

     从上面可以看出普通字段需要通过对象来访问,静态字段通过类来调用。

2:存储的位置

  1. 静态字段只存在把内存中一份,存在类的内存中
  2. 普通字段在每个对象中都要创建一份。

通过类创建对象的时候,如果每个对象都具有相同的字段,那么就使用静态字段

二:方法

普通方法、静态方法、类方法。三种方法在内存中都属于类,区别在于调用方式不同

  • 普通方法:由对象调用,至少一个self参数,执行普通方法时,自动将调用该方法的对象赋值给self
  • 类方法:由类调用,至少一个cls参数,执行类方法时,自动将调用该方法的类赋值给cls
  • 静态方法:由类调用,无默认参数
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

点睛:

  1. 定义时,在普通方法的基础上在上面添加@property装饰器
  2. 属性仅有一个self参数
  3. 调用时,无需括号

        方法:

              obj = Foo()

              ret = obj.func()

        属性:

              obj = Foo()

              ret = obj.prop

属性存在的意义:访问属性时,可以制造出和访问字段完全相同的假象

实例:

对于主机列表页面,每次请求不可能把数据库中的所有内容都显示到页面上,而是通过分页的功能局部显示,所以在向数据库中请求数据时就要显示的指定获取从第M条到第N条的所有数据,这个分页功能包括:

  1. 根据用户请求的当前和总数据条数计算出m和n
  2. 根据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的构造方法中有个四个参数

  • 第一个参数是方法名,调用对象.属性时自动触发执行方法
  • 第二个参数是方法名,调用对象.属性 = xxx时自动触发执行方法
  • 第三个参数是方法名,调用del 对象.属性时自动触发执行方法
  • 第四个参数是字符串,调用对象.属性.__doc__此参数是该属性的描述信息
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
'''

类成员的修饰符

两种形式:

  1. 私有成员:只有在类的内部才能访问的方法
  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 ,如需转载请自行联系原作者
相关文章
|
2月前
|
Python
你真的会面向对象吗!解密Python“魔术方法”
你真的会面向对象吗!解密Python“魔术方法”
24 0
|
5天前
|
前端开发 Python
Python编程的面向对象(二)—类的多态
Python编程的面向对象(二)—类的多态
12 7
|
4天前
|
IDE Java 开发工具
Python类与面向对象
Python类与面向对象
|
2月前
|
安全 算法 Go
Python面向对象的三大特性
python面向对象编程(OOP)的三大特性是封装、继承和多态。这些特性共同构成了OOP的基础,使得软件设计更加灵活、可维护和可扩展。
23 3
|
3月前
|
数据采集 网络协议 数据挖掘
网络爬虫进阶之路:深入理解HTTP协议,用Python urllib解锁新技能
【7月更文挑战第30天】网络爬虫是数据分析和信息聚合的关键工具。深入理解HTTP协议及掌握Python的urllib库对于高效爬虫开发至关重要。HTTP协议采用请求/响应模型,具有无状态性、支持多种请求方法和内容协商等特点。
39 3
|
3月前
|
数据采集 Java C语言
Python面向对象的高级动态可解释型脚本语言简介
Python是一种面向对象的高级动态可解释型脚本语言。
26 3
|
2月前
|
安全 Python
九:《Python基础语法汇总》— 面向对象
本篇文章讲解了何为类何为对象,以及魔法方法(具有特殊功能的函数)和面向对象编程的三个特性:封装;继承;多态
13 0
|
3月前
|
网络协议 开发者 Python
网络编程小白秒变大咖!Python Socket基础与进阶教程,轻松上手无压力!
【7月更文挑战第25天】在网络技术快速发展的背景下, Python因其简洁的语法和强大的库支持成为学习网络编程的理想选择。
59 5
|
3月前
|
网络协议 Python
网络世界的建筑师:Python Socket编程基础与进阶,构建你的网络帝国!
【7月更文挑战第26天】在网络的数字宇宙中,Python Socket编程是开启网络世界大门的钥匙。本指南将引领你从基础到实战,成为网络世界的建筑师。
54 2
|
3月前
|
开发者 Python
Python Socket编程:不只是基础,更有进阶秘籍,让你的网络应用飞起来!
【7月更文挑战第25天】在网络应用蓬勃发展的数字时代,Python凭借其简洁的语法和强大的库支持成为开发高效应用的首选。本文通过实时聊天室案例,介绍了Python Socket编程的基础与进阶技巧,包括服务器与客户端的建立、数据交换等基础篇内容,以及使用多线程和异步IO提升性能的进阶篇。基础示例展示了服务器端监听连接请求、接收转发消息,客户端连接服务器并收发消息的过程。进阶部分讨论了如何利用Python的`threading`模块和`asyncio`库来处理多客户端连接,提高应用的并发处理能力和响应速度。掌握这些技能,能使开发者在网络编程领域更加游刃有余,构建出高性能的应用程序。
24 3
下一篇
无影云桌面