关于python:Python面向对象之类的成员

6次阅读

共计 4709 个字符,预计需要花费 12 分钟才能阅读完成。

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

一、字段

字段能够分为动态字段、动静字段,上面通过代码展现类中的两种字段

class MyClass:

# 动态字段,属于类,多个对象共用一个动态字段
leader = "abuve"

def __init__(self):
    # 动静字段,属于对象,也能够叫一般的字段,每个对象都会有本人独有的动静字段
    self.name = "kevin"

动静字段在类的实例化过程中很常见,通过 self 为每个对象封装属于本人特有的数据,但如果类中全副采纳动静字段,也会遇到一些不合理的弊病,例如上面代码:

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 字段,这无疑减少了程序对内存的开销,因而更正当的形式应该应用动态字段,代码如下:

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、动静字段,属于对象,通过对象来调用拜访

对于上述代码,咱们通过上面的形式拜访其中的字段数据:

print it_dept.deptprint 
hr_dept.leaderprint 
Company.company_name

如果通过对象拜访动态字段同样能够拜访到数据,因为对象也是通过对象指针指向了本人的类,对象中没有的数据最终也会去类中查找,然而这样的调用形式并不合理。

通过对象调用,同样拜访到了类的动态字段

print it_dept.company_name

在字段前退出两个下划线,能够将该字段设置为公有字段,例如:

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 面向对象编程中,办法的调用最为常见,分为动静办法(一般办法)、静态方法、类办法,上面通过代码展现。

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、类办法,属于静态方法的一种,通过类来调用,执行的时候会主动将类名传递进去,因而要有一个默认的接管参数。

静态方法仍然也能够通过对象指针来拜访到,然而这样调用并不合理,之所以将这种略微非凡的办法写到类中,也是因为其与该类具备肯定的相关性。

三、属性

如果说字段属于右派、办法属于左派,那么属性就属于中立派,因为它即具备办法的性能,同时又能够通过字段的形式来拜访,上面为一段蕴含属性的代码段。

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 办法变为属性,那么该办法在被对象调用时,就像拜访字段一样,不须要再加括号了。此时咱们只实现了通过字段的形式来拜访办法,通过上面的代码,咱们也能够为属性调用相干的赋值、删除动作。

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 办法。

class MyClass:

def __call__(self):
    print 'This is something...'
    

if name == “__main__”:

object = MyClass()
object()

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

class MyClass:

def __str__(self):
    return 'This is text that I want to return...'
    

if name == “__main__”:

object = MyClass()    
print object

能够将两个对象中的内容进行相加。

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__
通过字典的形式操作对象,能够为其设置相应的执行动作。

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__
用于迭代器,返回一个能够被迭代的对象

class MyClass(object):

def __iter__(self):
    return iter([1,2,3,4,5]) 
    

if name == “__main__”:

obj = MyClass()    
for i in obj:        
    print i

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

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)
正文完
 0