首页 > 代码库 > python学习笔记-(十一)面向对象进阶&异常处理

python学习笔记-(十一)面向对象进阶&异常处理

上篇我们已经了解了一些面向对象的基础知识,本次就了解下面向对象的一些进阶知识(虽然我也不知道有什么卵用)。

 

静态方法

静态方法是一种普通函数,就位于类定义的命名空间中,它不会对任何实例类型进行操作。使用装饰器@staticmethod定义静态方法。类对象和实例都可以调用静态方法

说了那么多,估计会有些懵逼,咱们还是直接上代码看下静态方法怎么使用吧!

1.按照正常逻辑编写代码并加上@staticmethod定义静态方法eat:

class People(object):    def __init__(self,name):        self.name = name     @staticmethod #把eat方法变为静态方法    def eat(self):        print("%s is eating" % self.name) d = People("cc")d.eat()

运行上面代码,我们会发现报以下错误:

TypeError: eat() missing 1 required positional argument: ‘self

----------eat需要一个self参数,但调用时却没有传递

so...我们可以得出一个结论:eat变成静态方法后,再通过实例调用时不会自动把实例本身当作一个参数传给self

2.解决办法:

1)调用时主动传递实例本身给eat方法,即d.eat(d) 

class People(object):    def __init__(self, name):        self.name = name    @staticmethod  # 把eat方法变为静态方法    def eat(self):        print("%s is eating" % self.name)d = People("cc")d.eat(d)#------打印输出------#cc is eating

2)在eat方法中去掉self参数(这也意味着,在eat中不能通过self.调用实例中的其它变量了)

class People(object):    def __init__(self, name):        self.name = name    @staticmethod  # 把eat方法变为静态方法    def eat():        print("%s is eating" % self.name)d = People("cc")d.eat()#------------------打印输出----------------#print("%s is eating" % self.name)#NameError: name ‘self‘ is not defined

类方法

类方法是将类本身作为对象进行操作的方法。类方法使用@classmethod装饰器定义,其第一个参数是类,约定写为cls。类对象和实例都可以调用类方法。

类方法和普通方法的区别是, 类方法只能访问类变量,不能访问实例变量。

依然还是原来的代码,把eat变为类方法看下:

class People(object):    def __init__(self, name):        self.name = name    @classmethod  # 把eat方法变为类方法    def eat(self):        print("%s is eating" % self.name)d = People("cc")d.eat()---------------打印输出-------------------print("%s is eating" % self.name)AttributeError: type object ‘People‘ has no attribute ‘name‘

报错说明:People没有name属性;

上面说过,类方法只能访问类变量,不能访问实例变量,而name在这里就是实例变量。

我们加上一个类变量试试:

class People(object):    name = "类变量"    def __init__(self, name):        self.name = name    @classmethod  # 把eat方法变为类方法    def eat(self):        print("%s is eating" % self.name)d = People("cc")d.eat()--------------------打印输出-------------------类变量 is eating

属性方法

属性方法的作用就是通过@property把一个方法变成一个静态属性;

依然还是之前的代码,把eat方法变成静态属性看下效果:

class People(object):    name = "请叫我类变量"    def __init__(self, name):        self.name = name    @property  # 把eat方法变为静态属性    def eat(self):        print("%s is eating" % self.name)d = People("cc")d.eat()-----------------打印输出--------------------    d.eat()TypeError: ‘NoneType‘ object is not callable

这里报错是因为eat已经变成了一个静态方法,当然不能再使用()去调用了,我们直接调用试试:

d.eat-------------打印输出------------cc is eating

 

反射

1.反射的定义

根据字符串的形式去某个对象中操作成员

  • 根据字符串的形式去一个对象中寻找成员
  • 根据字符串的形式去一个对象中设置成员
  • 根据字符串的形式去一个对象中删除成员
  • 根据字符串的形式去一个对象中判断成员是否存在

2. 反射的函数

  • getattr(object, name[, default])

根据字符串的形式去一个对象中寻找成员

class People(object):    def __init__(self):        self.name = ‘cc‘    def eat(self):        return ‘HI‘d = People()ret1 = getattr(d,‘eat‘)ret2 = getattr(d,‘name‘)r1 = ret1()print(r1)print(ret2)--------------打印输出----------------HIcc
  • setattr(object, name, value)

根据字符串的形式去一个对象中设置成员

class People(object):    def __init__(self):        self.name = ‘cc‘    def eat(self):        return ‘HI‘d = People()set1 = setattr(d,‘age‘,18)r1 = getattr(d,‘age‘)print(r1)-----------------------打印输出---------------------------18
  • delattr(object, name)

根据字符串的形式去一个对象中删除成员

class People(object):    def __init__(self):        self.name = ‘cc‘    def eat(self):        return ‘HI‘d = People()del1 = delattr(d,‘name‘)r1 = getattr(d,‘name‘)print(r1)----------------打印输出-------------------AttributeError: ‘People‘ object has no attribute ‘name‘
  • hasattr(object, name)

根据字符串的形式去一个对象中判断成员是否存在

class People(object):    def __init__(self):        self.name = ‘cc‘    def eat(self):        return ‘HI‘d = People()h1 = hasattr(d,‘age‘)h2 = hasattr(d,‘name‘)print(h1,h2)---------------打印输出-----------------False True

 

异常处理

在之前学习的过程中我们会接触到各式各样的报错信息,编程过程中为了增加友好性,可以抓取相对应的错误并给出提示信息。

常用异常:

AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性xIOError 输入/输出异常;基本上是无法打开文件ImportError 无法引入模块或包;基本上是路径问题或名称错误IndentationError 语法错误(的子类) ;代码没有正确对齐IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]KeyError 试图访问字典里不存在的键KeyboardInterrupt Ctrl+C被按下NameError 使用一个还未被赋予对象的变量SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了)TypeError 传入对象类型与要求的不符合UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,导致你以为正在访问它ValueError 传入一个调用者不期望的值,即使值的类型是正确的

更多异常:

ArithmeticErrorAssertionErrorAttributeErrorBaseExceptionBufferErrorBytesWarningDeprecationWarningEnvironmentErrorEOFErrorExceptionFloatingPointErrorFutureWarningGeneratorExitImportErrorImportWarningIndentationErrorIndexErrorIOErrorKeyboardInterruptKeyErrorLookupErrorMemoryErrorNameErrorNotImplementedErrorOSErrorOverflowErrorPendingDeprecationWarningReferenceErrorRuntimeErrorRuntimeWarningStandardErrorStopIterationSyntaxErrorSyntaxWarningSystemErrorSystemExitTabErrorTypeErrorUnboundLocalErrorUnicodeDecodeErrorUnicodeEncodeErrorUnicodeErrorUnicodeTranslateErrorUnicodeWarningUserWarningValueErrorWarningZeroDivisionError

常用异常实例:

IndexError(输出指定错误信息并打印错误信息)

dic = [1,2]try:    dic[2]except IndexError as e :    print("i got it!\n",e)---------------------------打印输出--------------------------i got it!list index out of range

KeyError(输出指定错误信息并打印错误信息)

dic = {‘name‘:‘cc‘}try:    dic[‘age‘]except KeyError as e :    print("i got it!\n",e)---------------------------打印输出---------------------------i got it! ‘age‘

ValueError

s1 = ‘hello‘try:    int(s1)except ValueError as e:    print (e)---------------------------打印输出----------------------------invalid literal for int() with base 10: ‘hello‘

万能异常Exception:(不建议用,不便于调试;可与异常配合使用)

s1 = ‘hello‘try:    int(s1)except KeyError as e:    print(‘键错误‘)except IndexError as e:    print(‘索引错误‘)except Exception as e:    print(‘错误‘)

自定义异常:

class ccException(Exception):    def __init__(self,msg):        self.msg = msg    def __str__(self):        return self.msgtry:    raise ccException("我的异常")except ccException as e:    print(e) 

python学习笔记-(十一)面向对象进阶&异常处理