zoukankan      html  css  js  c++  java
  • [Python学习笔记][第六章Python面向对象程序设计]

    1月29日学习内容

    Python面向对象程序设计

    类的定义与使用

    类定义语法

    使用class关键词

    class Car:
        def infor(self):
            print("This is car")
    

    self参数

    类的所有实例方法都必须至少有一个名为self的参数,并且必须是方法的第一个形参

    self参数代表将来要创建的对象本身

    实际上也没可以不用self 而取别的名字,但这是约定俗成的事

    class A:
        def __init__(hahaha, v):
            hahaha.value=v
        def show(hahaha):
            return hahaha.value
    a=A(3)
    a.show()
    

    类成员与实例成员

    实例属性

    实例属性一般是指在构造函数init()中定义的,定义与使用必须以self作为前缀;

    类属性

    是在类中所有方法以外定义的数据成员

    两者区别

    在主程序中

    实例属性属于实例,只能通过对象名访问

    而类属性属于类 ,可以通过类名和对象名访问

    Python优点

    可以动态的为类对象增加成员

    私有成员和公有成员

    私有属性

    如果属性名以两个下划线”__”(中间无空)开头则表示是私有属性

    大多数跟其他语言一样,但是Python支持的特殊方式访问 对象._类名__xxx

    • _xxx

      这样的对象叫做保护成员,不能用”from module import *”导入,只有类对象和子类对象能访问这些成员

    • __xxx__

      系统定义的特殊成员,非私有成员

    • __xxx

      只有类对象自己能访问,子类对象也不能访问到这个成员,但可以用对象名._类名__xxx这样的特殊方式访问.

    方法

    共有方法

    通过对象名直接调用,在方法中也要用self

    如果通过类名来调用属于对象的共有方法,需要显示为改方法的self参数传递一个对象名,用来明确指定访问那个对象的数据成员

    公有方法

    __来命名

    不能通过对象名直接调用,只能在属于对象的方法中通过self调用或在外部通过特殊方法调用

    静态方法和类方法

    都可以通过类名和对象名来调用

    但只能访问属于类的成员,而不能访问属于对象的成员

    类方法

    一般将cls作为类方法的第一个参数名称.

    需要在前面加一个@classmethod的修饰符 表示下一个方法为类方法

    @classmethod
    def classShowTotal(cls):
        print(cls.__value)
    

    静态方法

    不需要参数名

    需要在前面加一个@staticmethod的修饰符 表示下一个方法为静态方法

    class Root:
        __total=0;
        def __init__(self,v):
            self.__value=v
            Root.__total+=1
    
        def show(self):
            print('self.__value:',self.__value)
            print('Root.__total:',Root.__total)
    
        @classmethod        #修饰符
        def classShowTotal(cls):    #类方法
            print(cls.__total)
    
        @staticmethod       #修饰符
        def staticShowTotal():
            print(Root.__total)
    r=Root(3)
    r.classShowTotal()          ##类方法可以用对象调用
    #1
    r.staticShowTotal()         ##静态方法也可以用对象调用
    #1
    r.show()
    #self.__value: 3
    #Root.__total: 1
    rr=Root(5)
    Root.classShowTotal()      ##类方法可以用类调用
    #2
    Root.staticShowTotal()     ##静态方法也可以用类调用
    #2
    Root.show(r)        ##为self显示传递对象名
    #self.__value: 3
    #Root.__total: 2    证明__total只有一个
    
    r.show()
    #self.__value: 3
    #Root.__total: 2
    

    属性

    python2.X的属性没有实质的意义 无法起到保护的作用。当建立一个只读的属性时
    如果修改其值,虽然并不会真正的修改,修改的时候其实是新建了一个变量会把这个属性隐藏。所以十分鸡肋

    python 3.X中 得到较为完整的实现

    用@property 标识符表示下一个方法是 属性方法

    用property(__get,__set__del)的方法设置 ,不需要的参数可以用None

    具体看以下代码

    只读属性

    class Test:
        def __init__(self,value):
            self.__value=value
        @property
        def value(self):
            return self.__value
    
    t=Test(3);
    print(t.value)
    #3
    t.value=5;
    #AttributeError: can't set attribute
    

    可读可修改

    class Test:
        def __init__(self,value):
            self.__value=value
        def __get(self):
            return self.__value
        def __set(self,v):
            self.__value=v;
        value=property(__get,__set)
    
    t=Test(3)
    print(t.value)
    #3
    t.value=5;
    print(t.value)
    #5
    

    可读可修改可删除

    class Test:
        def __init__(self,value):
            self.__value=value
        def __get(self):
            return self.__value
        def __set(self,v):
            self.__value=v;
        def __del(self):
            del self.__value
        value=property(__get,__set,__del)
    
    t=Test(3)
    print(t.value)
    #3
    t.value=5;
    print(t.value)
    #5
    del t.value
    

    系统自己补出的代码 有待研究 很厉害的样子

    class Test:
        def __init__(self,value):
            self.__value=value
        def value():
            doc = "The value property."
            def fget(self):
                return self.__value
            def fset(self, value):
                self.__value = value
            def fdel(self):
                del self.__value
            return locals()
        value = property(**value())
    

    特殊方法于运算符重载

    常用特殊方法

    • 构造函数__init()__
    • 析构函数__del()__
    • __add__() , __radd__()

      左+,右+

    • __sub__

    -

    • __mul__

      *

    • __div()_ ,__truediv_()

      Python 2.x使用div(),Python3.X使用turediv()

    • __floordiv__()

      整除

    • __mod__()

      取余

    • __pow__()

      **

    • __cmp__()

    • __repr__()

      打印 转换

    • __setitem__()

      按照索引赋值

    • __getitem__()

      按照索引获取值

    • __len__()

      计算长度

    • __call__()

      函数调用

    • __contains__()

      测试是否包含某个元素

    • __eq__() ,__ne__() ,__lt__() ,__le__() ,__gt__() ,__ge__()

      ==,!=,<,<=,>,>=

    • __str__()

      转化为字符串

    • __lshift__() ,__lshift__()

      <<,>>

    • __and__() ,__or__() ,__invert__()

      &,|,~

    • __iadd__() ,__isub__()

      +=,-=

    继承

    class 类名(继承的类名):
        pass
    

    有时间补充

    slots

    但是,如果我们想要限制实例的属性怎么办?比如,只允许对Student实例添加name和age属性。
    为了达到限制的目的,Python允许在定义class的时候,定义一个特殊的slots变量,来限制该class实例能添加的属性:

    class Student(object):
        __slots__ = ('name', 'age') # 用tuple定义允许绑定的属性名称
    

    使用slots要注意,slots定义的属性仅对当前类实例起作用,对继承的子类是不起作用的:

  • 相关阅读:
    需求的陷阱
    VS2008 NumericUpDown控件 内容全选
    KeyPress 事件中 keycode对应的按键
    C#发送邮件
    Stream 和Byte[] 之间的转换
    SQL ISNULL() 函数
    修改struts2的.action后缀名
    #pragma data_seg
    VBA中Option的四种用法
    SetWindowsHookEx
  • 原文地址:https://www.cnblogs.com/zy691357966/p/5480286.html
Copyright © 2011-2022 走看看