共计 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)