首页 > 代码库 > 面向对象进阶篇

面向对象进阶篇

上节补充

当创建对象的类中没有我们想要执行的方法是,我们知道应该从它的父类里面找,如果父类里面有我们想找的方法,而且放下下面又包含方法时,包含的方法怎么执行呢?

class A:
    def f1(self):
        print("A")
    def xxx(self):
        print("111")

class B:
    def f1(self):
        self.xxx()
        print("B")
    def xxx(self):
        print("222")

class C():
    def f2(self):
        print("C")
    def xxx(self):
        print("444")

class D(C,B):
    def f(self):
        print("D")
obj = D()
obj.f1()

 技术分享

我们知道对象可以执行自己的构造方法,那么我们既想对象执行自己的构造方法,又想执行父类的构造方法怎么办呢?

1、super(当前类名,self).__init__()    推荐使用

2、父类名.__init__(self)

class annimal:
    def __init__(self):
        self.name = "动物"
        print("构造方法A")
class cat(annimal):
    def __init__(self):
        self.tp = "喵"
        print("构造方法B")
        # super(cat,self).__init__()
        annimal.__init__(self)
obj = cat()
print(obj.__dict__)   #表示对象内所封装的成员

构造方法B
构造方法A
{‘name‘: ‘动物‘, ‘tp‘: ‘喵‘}

 派生类继承父类中init及方法中包含方法,找寻的思路(查找源码的过程

如果派生类里面没有__init__构造方法,则去其父类中寻找(必须有继承关系)

class annimal:
    def __init__(self):
        print("构造方法A")

    def f1(self):
        print("111")

class cat(annimal):
    def __init__(self):
        self.f1()
        print("构造方法B")
        super(cat,self).__init__()

obj = cat()            # cat()执行cat中__init__方法,__init__方法下又有self.f1 cat中没有f1方法去annimal中找
111
构造方法B
构造方法A

通过反射:通过类自能找类的成员

     通过对象既可以找对象里面的成员又可以找类里面的成员

 

本章将重点讲解python类的成员,成员修饰符,类的特殊成员

一、类的成员

类的成员可以分为三大类:字段、方法、特性

技术分享 

class qwe:
    age = 10                   #静态字段
    def __init__(self,name):  #构造方法
        self.name = name   # 普通字段
    def f1(self):          # 普通方法
        print("123")
    @staticmethod          #静态方法
    def f2(args,args1):
        print("zxx")
    @classmethod            #类方法
    def f3(cls):
        print(cls)
    @property               #特性(将方法伪造成字段)
    def f4(self):
        temp = self.name
        return temp
    @f4.setter
    def f4(self,value):
        print(value)
        self.name = value

a = qwe("111")
a.f1()
qwe.f2(1,2)
qwe.f3()
print(a.f4)
a.f4 = 456
print(a.f4)

 注:所有成员中,只有普通字段的内容保存在对象中,既根据此类在对象中创建了多个对象,在内存中就有多少个普通字段,而其他的成员,则都保存在类中,既无论对象多少,内存中只有一份

1、 类成员

技术分享

由上图可是:

  • 静态字段在内存中只保存一份
  • 普通字段在每个对象中都要保存一份

字段分为:普通字段:   普通字段属于对象,普通字段用于对象有不同标签的情况

      静态字段:    静态字段属于类,将每个对象中存在的东西在类中保存一份(多个方法共同用到的参数)

方法分为:普通方法:   def xxx(self)必须创建对象来访问方法

     静态方法:  通过在方法前加@staticmethod 而且方法中不用加self,而可以有其他参数       @staticmethod   不需要创建对象来访问方法

                                                   def xxx() 

     类方法:通过在方法前加@classmethod 而且方法中必须有cls(当前类的类名)                 @classmethod 

                                                         def xxx(cls)

特性:通过在方法前加@property将方法伪造成一种字段(以字段的形式访问方法)参数只能是一个self         @property

   通过 对象.方法(方法后没有括号)obj.f1                             def xxx(self)

下面的用于设置值

@property               
def f4(self):
    temp = self.name
    return temp
@f4.setter
def f4(self,value):

 

class qwe:
    age = 10    #静态字段,存在类中
    def __init__(self,name):  #构造方法,存在了类中
        self.name = name   # 普通字段,存在对象中
    def f1(self):          # 普通方法,存在类中
        print("123")
    @staticmethod          #静态方法
    def f2(args,args1):
        print("zxx")
    @classmethod            #类方法
    def f3(cls):
        print(cls)
    @property               #特性(将方法伪造成字段)
    def f4(self):
        temp = self.name
        return temp
    @f4.setter
    def f4(self,value):
        print(value)
        self.name = value

a = qwe("111")
a.f1()
qwe.f2(1,2)
qwe.f3()
print(a.f4)
qwe.f4 = 456
print(a.f4)

规定:自己的成员自己去访问(除了类中的普通方法(本身也可以但是我们不这样做))

通过类访问:   静态字段,静态方法、类方法(静态方法的特殊情况)

通过对象访问:静态字段,类的普通方法、类的特性

 

成员 :字段 :静态字段(每个对象都有一份),普通字段(每个对象都不同)

    方法 :静态方法(无需使用对象封装的内容),普通方法(使用对象封装的内容),类方法()

    特性 :普通特性(将一个方法伪造成字段的方式访问)

快速判断调用:有self==>对象调用

       无self==>类调用

2、类成员的修饰符

类的所有成员在上一步骤中已经做了详细的介绍,对于每一个类的成员而言都有两种形式:

  • 公有成员,在任何地方都能访问
  • 私有成员,只有在类的内部才能方法

私有成员和公有成员的定义不同:私有成员命名时,前两个字符是下划线。(特殊成员除外,例如:__init__、__call__、__dict__等)

class C:
    def __init__(self):

        self.name = ‘公有字段‘

        self.__foo = "私有字段"

静态字段

  公有静态字段:类可以访问;类内部可以访问;派生类中可以访问

  私有静态字段:仅类内部可以访问;

class C:
    
    def __init__(self):
        self.foo = "公有字段"

    def func(self):
        print self.foo  # 类内部访问

class D(C):
    
    def show(self):
        print self.foo # 派生类中访问

obj = C()

obj.foo     # 通过对象访问
obj.func()  # 类内部访问

obj_son = D();
obj_son.show()  # 派生类中访问

 

class C:
    
    def __init__(self):
        self.__foo = "私有字段"

    def func(self):
        print self.__foo  # 类内部访问

class D(C):
    
    def show(self):
        print self.__foo # 派生类中访问

obj = C()

obj.__foo     # 通过对象访问    ==> 错误
obj.func()  # 类内部访问        ==> 正确

obj_son = D();
obj_son.show()  # 派生类中访问  ==> 错误

 1、对于自己私有的自由自己能访问,其派生类和父类都不能访问(意思就是在自己内部可以访问)
成员修饰符:公有  任何地方都可以访问
   私有  只有在自己内部才可以访问,也可以在外部间接的访问私有的
如果在外面非要访问私有字段的话也可以通过 对象_类名__字段(或方法)
面向对象中一些常用特殊方法:__init__ 、__del__ 、

class Foo:
	__metaclass__ = MyType				#表示类由谁创建
	def __init__(self):					#r = Foo()		实例化对象
		print("xxx")
	def __call__(self,*args,**kwargs):  #r()            执行此方法
		print("xxx")
		return 1
	def __getitem__(self, item):		#r["xxx"]和r[x:x] 		执行此方法
		print(item)
	def __setitem__(self, key, value):	#r["xxx"] = 123 执行此方法
        print(key,value)	
	def __delitem__(self, key):			#del r["xxx"]   执行此方法
        print(key)

 __dict__获取类或对象里面的成员,用法:xxx.__dict__ 
__doc__获取注释

r = Foo() #在类后面加括号执行__init__

r() #在对象后面加括号执行__call__

m = Foo()() #先Foo()实例化一个对象执行__init__,再在对象后面加括号执行__call__

print(m) #获取对象加括号的返回值

2、异常处理

为了防止程序报一些未知的错误,不让用户看到大黄页(错误信息),而是可以把此转化到类外一个人性化的界面

inp = input("请输入内容:")
try:						#try里面就是捕获错误
    num = int(inp)
    print(num)
except IndexError as e:		#IndexError 表示捕捉索引错误(特定的错误)
    print("索引错误")
except Exception as e:		#这里的e表示封装了错误信息的对象,Exception表示所有类型错误的集合,是所有错误类的基类
    print(e)
技术分享 常用异常
技术分享 更多异常

异常其他结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
try:
    # 主代码块
    pass
except KeyError,e:
    # 异常时,执行该块
    pass
else:
    # 主代码块执行完,执行该块
    pass
finally:
    # 无论异常与否,最终执行该块
    pass

技术分享

主动触发异常

1
2
3
4
5
6
7
try:
    raise Exception(‘错误了。。。‘)
except Exception,e:
    print e

自定义异常

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class WupeiqiException(Exception):
    def __init__(self, msg):
        self.message = msg
    def __str__(self):
        return self.message
try:
    raise WupeiqiException(‘我的异常‘)
except WupeiqiException,e:
    print e

断言

1
2
3
4
5
# assert 条件
assert 1 == 1
assert 1 == 2

 

面向对象进阶篇