zoukankan      html  css  js  c++  java
  • Python 面向对象

     方法:所有的方法是属于类的

    1、普通方法:至少一个self,对象执行

    2、静态方法:任意参数,类执行

    3、类方法:至少一个cls,类执行

    类方法:

    在Python的面向对象方法中,支持3种,一种是普通方法,静态方法,类方法

    类方式其实是静态方法的一种特殊形式:

    class Foo:
        def __int__(self, name):
            self.name = name
    
        # 类方法是静态方法一种,由类来调用
        @classmethod
        def f2(cls):  # 必须至少要有一个参数cls
            print(cls)
    
    
    f = Foo()
    f.f2()  # 不用添加参数,自动把类名传入cls参数

     cls是类名,如果加上()就是创建对象

    属性

    class Pager:
        def __init__(self, all_count):
            self.all_count = all_count
    
        @property
        def all_pager(self):
            a1, a2 = divmod(self.all_count, 10)
            if a2 == 0:
                return a1
            else:
                return a1 + 1
    
    
    p = Pager(101)
    ret = p.all_pager
    print(ret)

    属性就是通过是用调用字段的方式调用类里面的方法(去掉括号),其它功能跟调用方法一致,在写代码的时候可能比较好看。

    但是问题来了,字段可以进行赋值,你这个可以吗?

    class Pager:
        def __init__(self, all_count):
            self.all_count = all_count
    
        @property
        def all_pager(self):
            a1, a2 = divmod(self.all_count, 10)
            if a2 == 0:
                return a1
            else:
                return a1 + 1
    
    
    p = Pager(101)
    p.all_pager = 10
    
    # 输出
    Traceback (most recent call last):
    File "D:/oop2.py", line 26, in <module>
    p.all_pager = 10
    AttributeError: can't set attribute

    比如我想对p.all_pager重新赋值为10,那程序肯定报错。

    那可以设置吗?

    答案是:肯定可以,如果你想设置需要在类里面创建一个方法,并在方法上加上一个装饰器@[方法名字].setter

    class Pager:
        def __init__(self, all_count):
            self.all_count = all_count
    
        @property
        def all_pager(self):
            a1, a2 = divmod(self.all_count, 10)
            if a2 == 0:
                return a1
            else:
                return a1 + 1
    
        @all_pager.setter
        def all_pager(self, value):
            print(value)
    
    
    p = Pager(101)
    
    p.all_pager = 10
    
    # 输出
    10

    上面我们介绍了,可以获取,可以设置,还缺少一个可以删除,那下面我们来实现删除

    实现删除其实跟实现设置一样,需要在类里面定义一个方法并在方法上加上@[方法名字].deleter

    class Pager:
        def __init__(self, all_count):
            self.all_count = all_count
    
        @property
        def all_pager(self):
            a1, a2 = divmod(self.all_count, 10)
            if a2 == 0:
                return a1
            else:
                return a1 + 1
    
        @all_pager.setter
        def all_pager(self, value):
            print(value)
    
        @all_pager.deleter
        def all_pager(self):
            print('del all_pager')
    
    p = Pager(101)
    
    del p.all_pager

    到此为止,属性伪造成字段的访问方式后,完全可以进行输出、设置、及删除了

    类继承-重构子类使用super的初始化方法

    class Member(object):
        def __init__(self, name, age, sex):
            self.name = name
            self.age = age
            self.sex = sex
    
    
    class Student(Member):
        def __init__(self, name, age, sex, sid):
            super(Student, self).__init__(name, age, sex)
            self.sid = sid
    
        def info(self):
            info = '''
            学生名称:{name}
            学生年龄:{age}
            学生性别:{sex}
            学生编号:{sid}
            '''.format(name=self.name, age=self.age, sex=self.sex, sid=self.sid)
            print(info)
    
    
    class Teacher(Member):
        def __init__(self, name, age, sex, tid, salary):
            super(Teacher, self).__init__(name, age, sex)
            self.tid = tid
            self.salary = salary
    
        def info(self):
            info = '''
            老师名称:{name}
            老师年龄:{age}
            老师性别:{sex}
            老师编号:{sid}
            老师工资:{salary}
            '''.format(name=self.name, age=self.age, sex=self.sex, sid=self.tid, salary=self.salary)
            print(info)
    
    
    s1 = Student('Tom', 18, '', 'S0001')
    s1.info()
    
    t1 = Teacher('jerry', 28, '', 'T0001', 0)
    t1.info()
    class Foo:
        def f1(self):
            print('foo f1')
    
    
    class Bar(Foo):
        def f1(self):
            super(Bar, self).f1()
            print('Bar f1')
    
    
    obj = Bar()
    obj.f1()

    类的多继承,适用于python 3.x

    class C_2:
        def f2(self):
            print('C-2')
    
    
    class C_1(C_2):
        def f2(self):
            print('C-1')
    
    
    class C0(C_2):
        def f1(self):
            print('C0')
    
    
    class C1(C0):
        def f1(self):
            pass
    
    
    class C2(C_1):
        def f2(self):
            print('c2')
    
    
    class C3(C1, C2):
        def f3(self):
            pass
    
    
    obj = C3()
    obj.f2()

    总结:

    当没有共同的父类的时候,深度优先,当有共同父类的时候广度优先

    类的魔术方法

    Python在类中存在一些特殊方法,被称为"魔术方法",下面我们来见识一下:

    1、__init__ 重要程度: *****

    按照字面的意思其实就是初始化,它在类中有什么用呢?相信学习面向对象的人第一个接触的就是它了,我的理解是:在实例化对象的时候被自动触发并执行

    class Foo:
        def __init__(self, name, age):
            self.Name = name
            self.Age = age
            print('我开始执行了')
    
    
    f = Foo('chen', 20)
    
    # 输出
    我开始执行了

    通过例子可以看出,我只是实例化了类,没有进行任何动作,就打印出来了

    2、__dict__ 重要程度: ***

    用于储存类或实例的属性,当使用类+__dict__打印类的属性,使用实例+__dict__打印实例的属性

    class Foo:
        country = 'CN'
    
        def __init__(self, name, age):
            self.Name = name
            self.Age = age
    
    f = Foo('chen', 20)
    print(f.__dict__)  # 以字典形式显示实例的属性
    print(Foo.__dict__)  # 以字典形式显示类的属性
    
    # output
    {'Name': 'chen', 'Age': 20}
    {'__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None, '__module__': '__main__', 'country': 'CN', '__init__': <function Foo.__init__ at 0x000000000377BA60>, '__dict__': <attribute '__dict__' of 'Foo' objects>}

     3、__doc__ 描述类的信息  重要程度: ***

    class Foo:
        """
        这是一个显示doc的类的例子
        """
        def __init__(self):
            pass
    
    print(Foo.__doc__)
    
    # 输出
    这是一个显示doc的类的例子

    4、__call__ 重要程度: *****

    在对象后边加(),触发__call__方法

    class Foo:
    
        def __call__(self, *args, **kwargs):
            print('调用我吧')
    
    f = Foo()
    f()

    5、__del__ : 析构方法 重要程度: *

    在垃圾回收前执行它,貌似没啥用

    6、__class__ 和__module__  重要程度: *

    class Foo:
        def __init__(self):
            pass
    
    
    f = Foo()
    print(f.__class__)
    print(f.__module__)
    
    # 输出
    <class '__main__.Foo'>
    __main__

    7、__str__

    使用这个方式打印f对象输出的是对象,那能否输出内容呢?答案是肯定的,使用__str__

    class Foo:
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
    f = Foo('tom', 11)
    print(f)
    
    # 输出
    <__main__.Foo object at 0x000000000337B278>

    修改一下代码:这样你在打印对象的时候就可以看见被封装的数据了

    class Foo:
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def __str__(self):
            return '{name}--{age}'.format(name=self.name, age=self.age)
    
    
    f = Foo('tom', 11)
    print(f)
    
    # 输出
    tom--11

     7、__add__

    8、__getitem__、__setitem__、__delitem__ 重要程度: *****

    搞清楚__getitem__之前,我们先看看字典的实现方法:

    dic = {'k1':'v1'} 等同于 dic = dict(k1=v1)

    当我们取值的时候,可以

    dic['k1'] 那这个怎么实现呢?

    只要在对象+[]中括号就是调用__getitem__方法

    class Foo:
    
        def __getitem__(self, item):
            print(item)
    
    f = Foo()
    f['abcd']
    
    # 输出
    abcd
    class Foo:
        def __setitem__(self, key, value):
            print(key, value)
    
    f = Foo()
    f['k1'] = 123
    class Foo:
    
        def __delitem__(self, key):
            print(key)
    
    
    f = Foo()
    del f['k1']

    利用上述模块,做一个有序字典,转自武sir

    class MyDict(dict):
        def __init__(self):
            super(MyDict, self).__init__()
            self.li = []
    
        def __setitem__(self, key, value):
            self.li.append(key)
            super(MyDict, self).__setitem__(key, value)
    
        def __str__(self):
            tmp_list = []
            for key in self.li:
                value = self.get(key)
                tmp_list.append("'%s':%s" % (key, value))
            temp_str = '{' + ','.join(tmp_list) + '}'
            return temp_str
    
    
    obj = MyDict()
    obj['k1'] = 123
    obj['k2'] = 123
    print(obj)

     

    9、__iter__

    默认对象是不可迭代的

    异常处理

    完整代码块:

    try:
        # 逻辑代码放这里
        pass
    except IndexError as e:  # 当逻辑处理块出现错误后,顺序查看错误原因,如果为IndexError这个块先进行处理,否则执行下边的except Exception语句
        print(e)  # str
    except Exception as e:
        print(e)
    else:
        # 逻辑处理块未出现异常,执行这里代码
        pass
    finally:
        # 释放资源
        # 不管你上边是否出现错误,本块永远执行,在逻辑处理块执行完毕后。
        pass
  • 相关阅读:
    VC实现开机自启动
    用Shell扩展实现源代码统计程序
    在(CListView)列表视图中添加右键菜单的方法
    关于打开外部程序并且发送一个按键消息 (转
    vc中运行外部程序的方法
    如何在 XCode 4.2 設定部分程式碼不使用 ARC 方式分享(转)
    Xcode调试断点不停止解决方案!(转)
    NSString+NSMutableString+NSValue+NSAraay用法汇总 (转)
    对于Retain和Assign属性的理解(转)
    基于Xcode4开发第一个iPhone程序:“Hello World”(转)
  • 原文地址:https://www.cnblogs.com/chen1930/p/5956076.html
Copyright © 2011-2022 走看看