Python面向对象之类的成员

简介:

 Python面向对象的编程过程中,我们为类实例化了对象,并通过对象指针来访问类中对应的资源,那么这些资源大体分为三大部分,分别是字段、方法和属性,我们将这三大块统称为类的成员。

一、字段

  字段可以分为静态字段、动态字段,下面通过代码展示类中的两种字段

1
2
3
4
5
6
7
class  MyClass:
     # 静态字段,属于类,多个对象共用一个静态字段
     leader  =  "abuve"
  
     def  __init__( self ):
         # 动态字段,属于对象,也可以叫普通的字段,每个对象都会有自己独有的动态字段
         self .name  =  "kevin"

  动态字段在类的实例化过程中很常见,通过self为每个对象封装属于自己特有的数据,但如果类中全部采用动态字段,也会遇到一些不合理的弊端,例如下面代码:

1
2
3
4
5
6
7
8
9
10
11
class  Company:
     def  __init__( self , dept, leader):
         self .company_name  =  "Center"
         self .dept  =  dept
         self .leader  =  leader  
           
     def  ...
     
if  __name__  = =  "__main__" :    
     it_dept  =  Company( "IT" "Abuve" )
     hr_dept  =  Company( "HR" "Kevin" )

  我们通过动态字段方式为对象封装了自己独有的数据,但是这里发现公司名称company_name都为“Center”,不管创建哪个部门的对象,公司名称是不变的,我们知道动态字段存放在对象中,这样每个对象就都包含了一份company_name字段,这无疑增加了程序对内存的开销,因此更合理的方式应该使用静态字段,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
class  Company:
     company_name  =  "Center"
 
     def  __init__( self , dept, leader):
         self .dept  =  dept
         self .leader  =  leader    
         
     def  ...
     
if  __name__  = =  "__main__" :
     it_dept  =  Company( "IT" "Abuve" )
     hr_dept  =  Company( "HR" "Kevin" )

同时在字段的调用方式上,我们也要遵循一些规则:
1、静态字段,属于类,通过类来调用访问
2、动态字段,属于对象,通过对象来调用访问

对于上述代码,我们通过下面的方式访问其中的字段数据:

1
2
3
print  it_dept.deptprint 
hr_dept.leaderprint 
Company.company_name

如果通过对象访问静态字段同样可以访问到数据,因为对象也是通过对象指针指向了自己的类,对象中没有的数据最终也会去类中查找,但是这样的调用方式并不合理。

1
2
# 通过对象调用,同样访问到了类的静态字段
print  it_dept.company_name

在字段前加入两个下划线,可以将该字段设置为私有字段,例如:

1
2
3
4
5
6
7
8
9
10
11
12
class  MyClass:
     def  __init__( self , name):
         self .__name  =  name 
         
     def  show( self ):
         print  self .__name
         
if  __name__  = =  "__main__" :
     object  =  MyClass( "Abuve" )     # 通过对象无法访问到私有字段
     print  object .__name     # 私有字段通过类的内部方法访问
     object .show()     # 通过类名前加入下划线的方式同样可以访问到
     print  object ._MyClass__name

最后一种方式通过类名前加入下划线的方式同样访问到了私有字段,但多数情况下尽量不要用这种方式进行访问。

二、方法

  在Python面向对象编程中,方法的调用最为常见,分为动态方法(普通方法)、静态方法、类方法,下面通过代码展示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class  MyClass:
     def  __init__( self , name):
         self .name  =  name 
         
     # 普通方法
     def  show( self ):
         return  self .name 
         
     # 静态方法
     @ staticmethod
     def  detail(name):
         print  '%s is good person.'  % name 
         
     # 动态方法
     @ classmethod
     def  show_detail( cls ):
         cls .detail( 'Kevin'
         
if  __name__  = =  "__main__" :
     object  =  MyClass( "Jack" )
     p_name  =  object .show()
     MyClass.detail(p_name)
     MyClass.show_detail()

与字段一样,方法的调用上依然要遵循一些规则。
1、普通方法,由对象调用
2、静态方法,由类调用
3、类方法,属于静态方法的一种,通过类来调用,执行的时候会自动将类名传递进去,因此要有一个默认的接收参数。

静态方法依然也可以通过对象指针来访问到,但是这样调用并不合理,之所以将这种稍微特殊的方法写到类中,也是因为其与该类具备一定的相关性。

三、属性

  如果说字段属于左派、方法属于右派,那么属性就属于中立派,因为它即具备方法的功能,同时又可以通过字段的方式来访问,下面为一段包含属性的代码段。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class  PageSet:
     def  __init__( self , count, page_size):
         self .count  =  count
         self .page_size  =  page_size 
         
     # 通过装饰器将page_num变为属性,对象调用时不需要再加括号
     @ property
     def  page_num( self ):
         page_count, remainder   =  divmod ( self .count,  self .page_size)    
             
         if  remainder  = =  0 :
             return  page_count
         else :
             return  page_count  +  1
         
if  __name__  = =  "__main__" :    
     # 传入条目总数,以及单页size大小
     page_tools  =  PageSet( 108 10 )    
     # 像访问字段一样执行了page_num方法
     print  page_tools.page_num

  上面的代码实现了一个分页设置,我们通过装饰器property将page_num方法变为属性,那么该方法在被对象调用时,就像访问字段一样,不需要再加括号了。此时我们只实现了通过字段的方式来访问方法,通过下面的代码,我们也可以为属性调用相关的赋值、删除动作。

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
31
class  PageSet:
     def  __init__( self , count, page_size):
         self .count  =  count
         self .page_size  =  page_size 
         
     @ property
     def  page_num( self ):
         page_count, remainder   =  divmod ( self .count,  self .page_size)        
         
         if  remainder  = =  0 :           
             return  page_count       
         else :            
             return  page_count  +  1
  
     @page_num.setter
     def  page_num( self , value):
         print  value        
         print  'This is set function.'
  
     @page_num.deleter
     def  page_num( self ):
         print  'This is delete function.'
         
if  __name__  = =  "__main__" :
     page_tools  =  PageSet( 108 10 )    
     # 调用property修饰属性
     page_tools.page_num    
     # 调用page_num.setter修饰属性
     page_tools.page_num  =  12
     # 调用page_num.deleter修饰属性
     del  page_tools.page_num

四、特殊成员

  特殊成员指函数两边都带有下划线的特殊方法,这些特殊方法为类提供独有的功能。

1、__init__ 
构造方法,这类方法最为常见,在我们实例化类的时候,就是通过__init__构造方法封装了对象的数据。

2、 __del__ 
析构函数,通过__del__函数构造特定功能,在为对象执行del操作时,可以自动调用该部分代码,在程序执行相关垃圾回收时,可以应用析构方法。

3、__doc__   
注释,通过对象,可以访问到__doc__函数中指定的注释内容。

4、__module__ 
通过该方法可以显示当前对象属于哪个模块。

5、__class__
通过该方法可以显示当前对象属于哪个类。

6、__call__ 
如果我们在类的实例化对象后面加括号时,会自动执行类中的call方法。

1
2
3
4
5
6
7
class  MyClass:
     def  __call__( self ):
         print  'This is something...'
         
  if  __name__  = =  "__main__" :
     object  =  MyClass()
     object ()

7、__str__
默认打印对象时,只能够显示内存地址,通过__str__可以显示想要返回的内容。

1
2
3
4
5
6
7
class  MyClass:
     def  __str__( self ):
         return  'This is text that I want to return...'
         
  if  __name__  = =  "__main__" :
     object  =  MyClass()    
     print  object

8、__add__
可以将两个对象中的内容进行相加。

1
2
3
4
5
6
7
8
9
10
11
class  MyClass:
     def  __init__( self , company, ceo):
         self .company  =  company
         self .ceo  =  ceo 
         
     def  __add__( self , other):
         return  "%s---%s"  % ( self .company, other.ceo)
  
obj1  =  MyClass( "A" , "Abuve" )
obj2  =  MyClass( "B" "Kevin" )
print  obj1  +  obj2

代码最终打印了 "A---Kevin"

9、__dict__ 
对象调用该方法,可以打印出所有封装的数据,类调用该访问可以打印出所有方法。

10、__getitem__、__setitem__、__delitem__
通过字典的方式操作对象,可以为其设置相应的执行动作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class  MyClass( object ):
     def  __getitem__( self , key):
         print  '__getitem__' ,key 
         
     def  __setitem__( self , key, value):
         print  '__setitem__' ,key,value 
         
     def  __delitem__( self , key):
         print  '__delitem__' ,key 
         
if  __name__  = =  "__main__" :
     obj  =  Myclass()      
     result  =  obj[ 'k1' ]    # 执行了__getitem__方法
     obj[ 'k2' =  'abuve'   # 执行了__setitem__方法
     del  obj[ 'k1' ]    # 执行了__delitem__方法

11、__iter__
用于迭代器,返回一个可以被迭代的对象

1
2
3
4
5
6
7
8
class  MyClass( object ):
     def  __iter__( self ):
         return  iter ([ 1 , 2 , 3 , 4 , 5 ]) 
         
if  __name__  = =  "__main__" :
     obj  =  MyClass()    
     for  in  obj:        
         print  i

12、isinstance/issubclass
通过isinstance可以判断某个对象的类型,issubclass可以判断某两个类是否为继承关系

1
2
3
4
5
6
7
8
9
class  Class1():
     pass
  class  Class2(Class1):
     pass
  if  __name__  = =  "__main__" :
     obj  =  Class2()     # 判断obj的类型是否为Class2
     print  isinstance (obj, Class2)     # isinstance同样也可以判断是否继承自父类
     print  isinstance (obj, Class1)    
     print  issubclass (Class2, Class1)







     本文转自阿布ve 51CTO博客,原文链接:http://blog.51cto.com/abuve/1812714,如需转载请自行联系原作者

相关文章
|
2月前
|
Python
你真的会面向对象吗!解密Python“魔术方法”
你真的会面向对象吗!解密Python“魔术方法”
25 0
|
6天前
|
前端开发 Python
Python编程的面向对象(二)—类的多态
Python编程的面向对象(二)—类的多态
13 7
|
5天前
|
IDE Java 开发工具
Python类与面向对象
Python类与面向对象
|
9天前
|
关系型数据库 MySQL Python
mysql之python客户端封装类
mysql之python客户端封装类
|
10天前
|
Python
python 类中的内置方法
python 类中的内置方法
|
8天前
|
Python
Python类中属性和方法区分3-8
Python类中属性和方法区分3-8
|
2月前
|
供应链 数据挖掘 Serverless
【python】美妆类商品跨境电商数据分析(源码+课程论文+数据集)【独一无二】
【python】美妆类商品跨境电商数据分析(源码+课程论文+数据集)【独一无二】
【python】美妆类商品跨境电商数据分析(源码+课程论文+数据集)【独一无二】
|
2月前
|
Python
12类常用的Python函数
12类常用的Python函数
|
2月前
|
存储 程序员 Python
Python类的定义_类和对象的关系_对象的内存模型
通过类的定义来创建对象,我们可以应用面向对象编程(OOP)的原则,例如封装、继承和多态,这些原则帮助程序员构建可复用的代码和模块化的系统。Python语言支持这样的OOP特性,使其成为强大而灵活的编程语言,适用于各种软件开发项目。
18 1
|
2月前
|
存储 程序员 C++
python类及其方法
python类及其方法
下一篇
无影云桌面