Python 面向对象
面向对象三大特性-封装:
封装,顾名思义就是将内容封装到某个地方,以后再去调用被封装在某处的内容。
所以,在使用面向对象的封装特性时,需要:
- 将内容封装到某处
- 从某处调用被封装的内容
1、将内容封装到某处。
class Foo: def __init__(self,name,age): # 构造方法,创建对象时自动执行。 self.name = name self.age = age # 创建对象,self = 对象本身 obj1 = Foo("steven",28) # 自动执行__init__方法,将 steven,28分别分装到 name,age中,保存在内存中 obj2 = Foo("author",28) # 自动执行__init__方法,将 author,28分别分装到 name,age中,保存在内存中
2、调用。
- 通过对象直接调用
class Foo: def __init__(self,name,age): # 构造方法,创建对象时自动执行。 self.name = name self.age = age # 创建对象,self = 对象本身 obj1 = Foo("steven",28) # 自动执行__init__方法,将 steven,28分别分装到 name,age中 obj2 = Foo("author",28) # 自动执行__init__方法,将 author,28分别分装到 name,age中 print obj1.name,obj1.age print obj2.name,obj2.age
通过self简介调用
class Foo: def __init__(self,name,age): # 构造方法,创建对象时自动执行。 self.name = name self.age = age def fun1(self): print self.name print self.age # 创建对象,self = 对象本身 obj1 = Foo("steven",28) # 自动执行__init__方法,将 steven,28分别分装到 name,age中 obj2 = Foo("author",28) # 自动执行__init__方法,将 author,28分别分装到 name,age中 obj1.fun1() obj2.fun1() Python默认会将obj2传给self参数,即:obj1.detail(obj1),所以,此时方法内部的 self = obj1,即:self.name 是 Steven ; self.age 是 28
面向对象三大特性-继承:
多继承:
Python的类如果继承了多个类,那么其寻找方法的方式有两种,分别是:深度优先和广度优先
- 当类是经典类时,多继承情况下,会按照深度优先方式查找
- 当类是新式类时,多继承情况下,会按照广度优先方式查找
class D: def bar(self): print 'D.bar' class C(D): def bar(self): print 'C.bar' class B(D): def bar(self): print 'B.bar' class A(B, C): def bar(self): print 'A.bar' a = A() # 执行bar方法时 # 首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去D类中找,如果D类中么有,则继续去C类中找,如果还是未找到,则报错 # 所以,查找顺序:A --> B --> D --> C # 在上述查找bar方法的过程中,一旦找到,则寻找过程立即中断,便不会再继续找了 a.bar() 经典类多继承
class D(object): def bar(self): print 'D.bar' class C(D): def bar(self): print 'C.bar' class B(D): def bar(self): print 'B.bar' class A(B, C): def bar(self): print 'A.bar' a = A() # 执行bar方法时 # 首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去C类中找,如果C类中么有,则继续去D类中找,如果还是未找到,则报错 # 所以,查找顺序:A --> B --> C --> D # 在上述查找bar方法的过程中,一旦找到,则寻找过程立即中断,便不会再继续找了 a.bar() 新式类多继承
经典类:首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去D类中找,如果D类中么有,则继续去C类中找,如果还是未找到,则报错
新式类:首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去C类中找,如果C类中么有,则继续去D类中找,如果还是未找到,则报错
注意:在上述查找过程中,一旦找到,则寻找过程立即中断,便不会再继续找了
面向对象三大特性-多态:
class F1: pass class S1(F1): def show(self): print 'S1.show' class S2(F1): def show(self): print 'S2.show' def Func(obj): print obj.show() s1_obj = S1() Func(s1_obj) s2_obj = S2() Func(s2_obj)
普通字段和静态字段
class Too: # 静态字段,只在类里面保存 country = "china" # 普通字段 def __init__(self,name): # 普通字段,可以存在对象中 self.name = name # 普通方法 def show(self): print "asf"
谁的属性,谁去访问:即静态字段尽量类来访问,普通字段尽量对象访问
利用反射查看面向对象成员归属
test.py
class Too: # 静态字段,只在类里面保存 country = "china" # 普通字段 def __init__(self,name): temp = "xxx" # 普通字段,对象中 self.name = name # 普通方法 def show(self): print "asf"
# 查看类中是否有show方法 ret1 = hasattr(Too,'show') # 查看类中有哪些成员,方法 ret2 = Too.__dict__ # 去对象中找成员或者方法,即在对象找不到,就会找对象的类 obj = Too("steven") ret3 = hasattr(obj,'name') ret4 = hasattr(obj,"show")
test.py
# 导入模块 m = __import__("test1",fromlist=True) # 去模块中找类 class_name = getattr(m,'Too') # 根据类创建对象 obj = class_name("steven") # 去对象中找成员 print getattr(obj,'name') ############ 返回结果 ############# True {'country': 'china', '__module__': 'test1', '__doc__': None, '__init__': <function __init__ at 0x10177f140>, 'show': <function show at 0x10177f578>} True True steven
静态方法,类方法,property,cls.setter:
class foo: """ 规范:静态方法和静态字段都由类来访问。 静态方法存在的意义,不需要对象就可以访问该方法。 """ name = "静态字段" # 静态方法,没有self,相当于类的方法。 @staticmethod def staticMethod(arg1,arg2): print arg1,arg2,"@staticmethod 专门装饰类中的方法,被装饰的方法变成了静态方法" def yo(self): print "普通方法" @classmethod def clsMethod(cls): print "类方法:%s 通过类来访问"%cls @property def pro(self): ret = "name: %s 以字段的方式访问该方法"% self.name return ret @pro.setter def pro(self,value): ret = "设置pro方法。" self.name = value print self.name # 通过类调用静态方法, foo.staticMethod("class",1) # 通过对象调用静态方法, 不推荐。 f = foo() f.staticMethod("object",2) # 通过类来访问类方法 foo.clsMethod() # 调用pro print f.pro # 设置pro f.pro=123
总结:
成员:
字段 静态字段(对象中有重复的字段时用该字段),普通字段(每个对象需要传输不通数据的时候用该该字段)
方法 静态方法(无需使用对象来调用的时候,即直接当函数调用)、类方法(类似静态方法,会传类名)、普通方法(需要用到对象的数据)
特性 普通特性(将方法伪造成字段)
判断什么时候类执行,什么时候对象执行:
self 对象调用
无self 类调用
成员修饰符: