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 # 静态方法@staticmethoddef detail(name): print '%s is good person.' %name # 动静办法@classmethoddef 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变为属性,对象调用时不须要再加括号@propertydef 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 @propertydef 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.setterdef page_num(self, value): print value print 'This is set function.'@page_num.deleterdef 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的类型是否为Class2print isinstance(obj, Class2) # isinstance同样也能够判断是否继承自父类print isinstance(obj, Class1) print issubclass(Class2, Class1)