面向对象进阶

来源:互联网 发布:单片机软件工程师苏州 编辑:程序博客网 时间:2024/05/17 02:28

继承补充:

派生类可以直接使用基类中的方法:
下例中基类有继承,派生类找继承来的bar方法时,可以直接以类D为对象来调用bar方法。
派生类本身是没有bar方法的,他的bar方法是继承基类来的。
bar方法查找过程: D =》 C =》 B =》 A.bar,继承A类中的bar方法,使用的self就变成了D。

class A:    def bar(self):    print("BAR")    self.f1()class B(A):    def f1(self):    print("B")class C:    def f1(self):    print("C")class D(C, B):    passd1 = D()d1.bar()

执行其父类的构造方法
使用super(Cat, slef).init()来调用基类中的函数:

class Annimal:    def __init__(self):        print("A构造方法")        self.ty = "动物"class Cat(Annimal):    def __init__(self):        print("B构造方法")        self.n = "猫"        super(Cat, self).__init__()c = Cat()print(c.__dict__)

通过反射来判断对象里面的成员:
反射,如果操作的对象是个类的话,则只能找类里面的成员
如果操作的是对象,则既可找对象,也可以找类的成员

class Foo:    def __init__(self, name):        self.name = name    def show(self):        print("show")obj = Foo("xiaoming")r = hasattr(obj, "name")print(r)r = hasattr(obj, "show")print(r)r = hasattr(Foo, "name")print(r)

**方法:**__init__ 查看类里面的所有方法

print(Foo.__dict__)

利用反射查找类中的内容:

#导入模块m = __import__("s2", fromlist=True)#去模块中找类class_name = getattr(m, "Foo")#根据类创建对象obj = class_name("xiaoming")#去对象中找name对应值val = getattr(obj, "name")print(val)

面向对象之成员

普通字段:保存在方法中的语句
普通方法:上面类中写的方法都是普通方法

静态字段
将每个对象中同时多次重复的字段,写入类中。以最少的字符,占用最少的内存达成同样作用。

class Provice:#静态字段    country = "中国"    def __init__(self, name):        temp = "xxx"        #普通字段,对象中        self.name = name    #普通方法,类中    def show(self):        print("shwo")hebei = Provice("河北")henan = Provice("河南")

静态方法

@staticmethod:定义方法的语句
静态方法与类方法的不同在于,静态方法没有默认参数self。普通方法,会默认将对象self传入参数。但静态方法没有这个功能。

class Provice:#静态字段country = "中国"    def __init__(self, name):        temp = "xxxx"        self.name = name    #普通字段,对象中    @staticmethod    #定义静态方法用的字符    def xo(arg1, arg2):        print("xo")    #普通方法    def show(self):        print("show")Provice.xo(1, 2)

类方法:
@classmethod:定义类方法的语句
类方法默认将类名上传到参数中

class Provice:    @classmethod    def xxo(cls):   #最少要有个cls参数        print("xxo", cls)Provice.xxo()xxo <class '__main__.Provice'>

特性(属性):
@property:定义特性的方法
将普通方法伪装成一个可以访问的字段,调用时可以直接使用调用静态字段的方式使用。

class Provice:    def start(self):        print("ddal")    @property    #添加后变成特性    def end(self):        return "daf"obj = Provice()ret1 = obj.start()print(obj.end)    #这里直接加 .end使用,不用加括号和参数

(2)设置特性
@setter:设置

class Provice:    @property    def end(self):        temp = "%s da" % self.name        return temp    @end.setter     #这里用这个格式,可以给特性配置一个参数    def end(self, value):        print(value)        self.name = valueobj = Provice()obj.end = "xiaoxiao"print(obj.end)

总结:

三大特性:封装,继承,多态

规范:
类,对象都可以访问,静态方法,普通方法,静态字段,普通字段。但为了代码一致我们使用下面的规范:

  1. 通过类访问:静态字段,静态方法,类方法
  2. 通过对象访问:普通字段,类的方法

成员使用情况:
字段:静态字段(每个对象都有同样数据的情况下使用),普通字段(每个对象的数据都不相同的情况下使用)

方法:静态方法(不需要使用对象内容的情况下使用),类方法(使用常见相似,会把类名传入参数),普通方法(使用对象中数据的情况下)

特性:普通特性(将方法伪装成字段,用对象调用);静态特性()

判断是用类执行还是用对象执行:
有self的用对象调用
没有self的用类调用


成员修饰符

为了起到开放封闭的作用,(__内容)在需要修饰的字段或方法前添加两个下划线来表示成员修饰符。

特性:修饰符不能被在外部调用,也不可以被派生类调用。只能在自己内部调用。

        普通字段,普通方法,静态字段和静态方法,如果加上修饰符以后,都不能在外部被直接调用
class Foo:    xo = "xo"    __ox = "ox"    def __init__(self, age, name):        self.age = age        self.__name = name    def fetch(self):        print(self.__name)obj = Foo("17", "ming")   #创建对象并传入参数print(obj.__name)   #直接调用,无法调用print(Foo.xo)   #调用静态字段print(Foo.__xo)     #不可直接调用有修饰符的静态字段

上面这种方法是编程语言中通用的,还有一个Python中特有的修饰符,但应用不广泛。

作用:在外部通过特定格式的调用语句来实现调用
print(obj._Foo__name)


面向对象常用方法

面向对象已知常用方法:

__init____del__
__call__ 方法class Foo:    def __init__(self):        print("init")    def __call__(self, *args, **kwargs):        print("call")        return 1#Foo()   #类名后面加括号,执行__init__方法r = Foo()()  #类后面加两个括号,第一个括号代表执行__init__方法,第二个括号代表执行call方法。并将结果赋值给rprint(r)
方法:对象.__getitem__对象.__setitem__对象.__delitem__class Foo:    def __init__(self):        self.name = "xiaoming"    def __getitem__(self, item):      #对象后面跟中括号执行__getitem__方法        print(item)    def __setitem__(self, key, value):    #对象后面跟中括号再跟等号,执行__setitem__方法        print(key, value)    def __delitem__(self, key):   #对象后面跟中括号,删除对象中的key并输出删除的内容        print(key)r = Foo()   #创建一个对象r["abc"]    #获取上传上去的对象,执行方法__getitem__r['abc'] = 123  #像字典一样定义一个key值和value值,并输出。执行方法__setitem__del r["dadd"]   #像字典一样删除一个key值,并输出,执行方法__delitem__print(r.__dict__)    #__dict__ 查看方法里的内容print(Foo.__dict__)     #__dict__查看类中的内容
方法:类名.__dict__ :以字典的形式获取类里面的内容class Foo:    def __init__(self):        self.name = "xiaoming"    def __getitem__(self, item):        print(item)    def __setitem__(self, key, value):        print(key, value)    def __delitem__(self, key):        print(key)        print(Foo.__dict__)执行结果:{'__delitem__': <function Foo.__delitem__ at 0x000000000072C620>, '__dict__': <attribute '__dict__' of 'Foo' objects>, '__getitem__': <function Foo.__getitem__ at 0x000000000072C400>, '__init__': <functio......}
对象.__iter__ :迭代,for循环对象的时候,自动运行__iter__方法yield :生成器,生成字符。两个集合起来就表示这个方法可以迭代生成class Foo:    def __init__(self):        self.name = "xiaoming"    def __iter__(self):        yield 666        yield 888        yield "dalj"obj = Foo()for i in obj:print(i)

异常处理程序

执行时,因为不同的原因造成报错。对这些报错信息加工,这个过程就叫做异常处理。

基本格式:

inp = input("请输入数字:")try:    #如果出错,就捕获错误num = int(inp)print(num)except Exception as e:print("数据错误", e)

常见错误类型:

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

例子:

dic = ["xiao", "ming"]try:        dic[5]except IndexError as e:    #指定错误类型并起一个          别名    print(e)

list index out of range

常见的错误类型只能处理固定的单一错误。如果错误类型不是指定的错误时则会报错。
为了使所有错误类型都可以被显示,就有了万能错误类型:Exception
Exception 能够接收所有的错误类型

dic = ["xiao", "ming"]try:dic["xa"]except IndexError as i:print(i)except ValueError as v:print(v)except Exception as e:print(e)

上面的代码,在执行的时候会从上到下依次判断错误类型。
使用指定的错误类型,能够让错误类型输出更加准确。

完整错误异常结构:

dic = ["xiao", "ming"]try:dic["xa"]except IndexError as i:print("判断错误类型并输出")else:print("如果except执行成功则执行")finally:print("无论执行成不成功都要执行我")

主动触发异常:raise
代码执行成功则主动触发异常生效,代码错误则按照异常处理来执行,有点没事找事的意思。

dic = ["xiao", "ming"]try:dic[1]raise Exception("出错.....")    #上面的代码执行成功,给exception定义一个对象(出错)except Exception as e:    #上一句定义的对象会赋值给eprint(e)    #执行这个对象

补充类中的特殊方法:

__str__:如果直接print(对象)的时候,将对象的内容以字符串的形式显示class dema:def __init__(self, ma):self.de = madef __str__(self):    #使用__str__方法return self.de    #__str__方法要和return结合,可以执行返回对象obj = dema("lalallalalal")print(obj)    #直接print(对象)就会触发__str__方法,直接以字符串的形式输出对象

断言:assert
指定条件,如果成立则为True,如果不成立则为False。类似与简写的判断

assert 1 == 1    #成立则成功assert 1 == 2    #不成立则会报错
0 0
原创粉丝点击