zoukankan      html  css  js  c++  java
  • Python学习笔记四:面向对象编程

    一:定义类并创建实例

        Python中定义类,通过class关键字,类名开头大写,参数列表为所继承的父类。如果没有需要明确继承的类,则继承object。

        使用类来创建对象,只需 类名+() 形式即可,python中没有new创建对象的。

    class Person(object):
        pass
    
    xiaoming = Person()
    xiaohong = Person()

    二:动态改变的类属性

        Python可以在创建实例后,通过实例来添加属性。而不是直接在类中定义好所有属性,并且同一个类的不同对象,可以在运行期间添加不同的属性。

    xiaoming = Person()
    xiaoming.name = 'Xiao Ming'
    xiaoming.gender = 'Male'
    xiaoming.birth = '1990-1-1'

    //给xiaohong加上的属性不一定要和xiaoming相同: xiaohong = Person() xiaohong.name = 'Xiao Hong' xiaohong.school = 'No. 1 High School' xiaohong.grade = 2

    三:在类中定义所有对象的公有属性(实例属性,不同实例内容不同)

        虽然对象可以动态地赋予属性,但是同一类的对象有很多属性是公有的,那么这些属性就可以在类中定义,并且可以通过类的构造函数在创建对象时赋值。 

       可以为类添加一个特殊的__init__()方法,当创建实例时,__init__()方法被自动调用,我们就在这个方法中定义并赋值公有属性。

        需要注意的是:__init__() 方法的第一个参数必须是 self(self相当于this指针),后续参数则可以自由指定,和定义函数没有任何区别。而在创建实例时,只需传递后续参数即可。 

    class Person(object):
        def __init__(self,name,gender,birth,job):
            self.name=name
            self.gender=gender
            self.birth=birth
            self.job=job
    
    xiaoming = Person('Xiao Ming', 'Male', '1990-1-1', job='Student')

    四:Python中的访问权限

        Python对属性权限的控制是通过属性名来实现的,如果一个属性由双下划线开头(__),该属性就无法被外部访问。但是,如果一个属性以"__xxx__"的形式定义,那它又可以被外部访问了,以"__xxx__"定义的属性在Python的类中被称为特殊属性。

     (其实,python根本没有权限控制,只能靠约定。我们约定 _XX 变量是私有属性,但其实是可以从外部访问的;我们用 __XX 变量实现私有,其实python底层会把该变量转变为  _ClassName_VarName  的变量名。所以我们仍然可以通过 _ClassName_VarName 的形式访问到类中 __XX形式命名的“私有变量”)

    五:类属性(不同实例共享同一属性值)

        绑定在类上面的属性,被所有实例共享,通过 类名.属性名 访问。

       定义类属性很简单,在定义类时,写在方法外即可。

       (注意:操作类变量时,要通过 类名.变量名 来操作,不然不起效)

    class Person(object):
        count=0
        def __init__(self,name):
            self.name=name
            Person.count=Person.count+1//类名.变量名操作类变量

         当实例属性和类属性重名时,实例属性优先级高,它将屏蔽掉对类属性的访问。

    六:实例方法

        实例的方法就是在类中定义的函数,它的第一个参数永远是 self,指向调用该方法的实例本身,其他参数和一个普通函数是完全一样的。

        在实例方法内部,可以访问所有实例属性,这样,如果外部需要访问私有属性,可以通过实例方法调用而获得。

    class Person(object):
        def __init__(self, name, score)://构造函数
            self.name = name
            self.score = score
        def get_grade(self)://实例函数
            return 'A'

    七:类方法

        类方法被所有实例共用,定义类方法时需要 @classmethod 注解。

        @classmethod修饰的方法将绑定到类上,而非类的实例。类方法的第一个参数将传入类本身,通常将参数名命名为 cls。

        @classmethod
        def how_many(cls)://cls相当与类本身
            return cls.__count //所以这里相当于 ClassName.属性

    (这里区分一下函数与方法:函数是一个代码块,可以在代码中通过  函数名()  的形式调用;

                                        方法也是一个函数,但方法是存在与一个类中的。所以我们称呼类中定义的函数为方法,称呼类外定义的为函数。)

    (在Python中,方法也是类的属性之一。所以可以通过  className.方法名  访问这个方法,或把它赋值给某变量func;调用方法则加()即可,如:func()则调用了所赋值的类中的对应方法。)

        

    八:继承

       注意两点:一:定义类时,在 类名(继承类列表) 括号中指明继承的父类(继承的父类用 , 分隔)

                     二:在子类的构造函数中,通过   super(子类名, self).__init__(父类构造函数参数列表) 初始化父类;    

    class Person(object)://定义父类
        def __init__(self, name, gender)://父类构造函数
            self.name = name
            self.gender = gender
    
    class Teacher(Person)://继承父类
        def __init__(self, name, gender, course)://子类构造函数
            super(Teacher,self).__init__(name,gender)//初始化父类
            self.course=course//子类新增的属性

    子类中调用父类方法的两种方式:

    方法一:
    super(子类名,self).父类方法名(args)
    
    方法二:
    父类名.方法名(args)

    九:类型判断

        函数 isinstance(实例,类型) 可以判断一个变量是否属于某个类型。

    十:动态语言的多态

        在调用类中方法时,实例变量优先从自己所属类型寻找函数,找不到则往继承链上寻找,主要找到就调用。

        这是动态语言和静态语言(例如Java)最大的差别之一。动态语言调用实例方法,不检查类型,只要方法存在,参数正确,就可以调用

    十一:动态获取对象的详细信息

     isinstance(obj,class) 判断它是否是某种类型

     type(obj) 函数获取变量的类型

    dir(obj) 函数获取变量的所有属性

    要获取或者设置对象的具体属性,就需要用 getattr() 和 setattr( )函数

    十二:特殊方法(magic method)【前后有两下划线的方法】

        python中的类自带了一些特殊方法,如:__str__()/__len__()等。

        创建一个Python对象时,实际上进行了两步操作:首先是调用了类中的__new__(cls)方法新建对象,然后调用__init__(args)方法为对象初始化赋值。

        __del__()方法是析构方法,用于回收Python对象时调用。

       在某些操作,如打印、排序等时,会自动调用默认的特殊方法。如果我们想按自己的思路来实现这些功能,则可以在定义类时,重写这些特殊方法。

       常见需要重写的方法有:

    __str__():定义该类的对象如何以字符串形式输出

    __cmp__():定义该类对象的比较方法,用于排序方法时调用。__cmp__用实例自身self和传入的实例 s 进行比较,如果 self 应该排在前面,就返回 -1,如果 s 应该排在前面,就返回1,如果两者相当,返回 0。

     __slots__(str,str...):定义了该类可以拥有的属性,目的是限制当前类所能拥有的属性,禁止实例动态添加属性。

    __call__(参数):call方法可以把类定义为一个可调用对象,直接通过 类名(参数) 即可调用类中定义的call方法。

    运算符重载:

    比较运算类魔术方法:

    四则运算魔术方法:

    逻辑运算魔术方法:

    在定义好上面的几种运算符魔术方法后,在代码中,对类实例对象的 +-*/,&&,||,==,>,<等符号运算就会自动调用类中重载过的相应魔术方法

    类的展现方法重载:

    repr方法是把对象转为机器码字符串,str方法是转为给人看的字符串。

    重写dir方法可以选择性地打印类中的属性,某些重要的属性可以不显示出来。

    重写类的属性操作方法:

    设置对象属性:__setattr__(self,name,value):注意方法中不能调用自身。

    查询对象属性:__getattr__(self,name)

                       __getattribute__(self,name):重写这个方法的话,最终还是要调用父类的 super(Subclass,self).__getattribute__()来查询属性,否则会递归栈溢出。

    删除对象属性:__delattr__(self,name):

  • 相关阅读:
    工作中的几个问题
    linux初学之二
    VMWARE虚拟机卡死
    记昨天、今天的部分工作内容及问题
    linux初学之一
    今日阅读项目源码
    python POST XML
    python的超简单WEB服务器
    在notepad++中运行python
    安装python图形库:Matplotlib
  • 原文地址:https://www.cnblogs.com/ygj0930/p/6892694.html
Copyright © 2011-2022 走看看