首页 > 代码库 > 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学习笔记-(十一)面向对象进阶&异常处理