Python面向对象

1.定义一个类

Python面向对象_第1张图片
老式类

1.1老式类与新式类:

Python面向对象_第2张图片
image.png

1.2两个内建函数:

Python面向对象_第3张图片
dir():返回对象的属性 type():返回对象的类型

1.2.1对比代码:

输出两个类的属性和类型


Python面向对象_第4张图片
输出两个类的属性和类型

1.2.2结果:

Python面向对象_第5张图片
新式类多了很多内置属性

2.定义类的属性

2.1直接在类里定义:

Python面向对象_第6张图片
属性被所有实例共享

2.2在构造函数里定义:

Python面向对象_第7张图片
为每一个实例赋各自的值

3.访问控制:

Python面向对象_第8张图片
尴尬

Python面向对象_第9张图片
name-->公有的;_age-->私有的;__weight-->也是私有的(类外不可访问,但有例外)

Python面向对象_第10张图片
例子

Python面向对象_第11张图片
输出

用最后一个输出语句可以访问双下滑线的所谓的私有属性
双下滑线的属性,python会把它的名字改一下而已,并没有进行真正的进行访问控制


4.定义类的方法

在python中一切皆对象
类的方法也是类的属性


Python面向对象_第12张图片
把一个方法改成了一个字符串

4.1方法的访问控制

Python面向对象_第13张图片
也是没有

Python面向对象_第14张图片
image.png

4.2特殊的装饰器

Python面向对象_第15张图片
感觉就像java的静态方法

Python面向对象_第16张图片
可怕

4.2.1一个例子

Python面向对象_第17张图片
上面没显示的代码和前面的代码一样

Python面向对象_第18张图片
结果

5.类的继承

5.1定义类的继承

class DerivedClassName(BaseClassName):
    
    ·
    ·
    ·
    

5.1.1继承的子类:

  • 会继承父类的属性和方法
  • 也可以自己定义,覆盖父类的属性和方法

5.1.2用super()调用父类的方法

class A(object):
    def method(self,arg):
        pass

class B(A):
    def method(self, arg):
        super(B, self).method(arg)

或者直接调用,但这样体现不出来继承

class A(object):
    def method(self, arg):
        pass

class B(A):
    def method(self, arg):
        A.method(arg)

5.1.3子类的类型判断

两个方法

  • isinstance - 判断类型
  • issubclass - 判断是否是子类

5.2多继承

class DerivedClassName(Base1, Base2, Base3):
    
    ·
    ·
    ·
    

5.3实例代码

#coding:utf-8
class Programer(object):# 定义了一个父类
    hobby = 'Play Computer'

    def __init__(self, name, age, weight):
        self.name = name
        self._age = age
        self.__weight = weight

        @classmethod
        def get_hobby(cls):
            return cls.hobby

        @property
        def get_weight(self):
            return self.__weight

        def self_introduction(self):
            print 'My Name is %s \nI am %s years old\n' % (self.name, self._age)

class BackendProgramer(Programer):# 定义子类继承父类

    def __init__(self, name, age, weight, language):
        super(BackendProgramer, self).__init__(name, age, weight)
        self.language = language

if __name__ == '__main__':

    programer = BackendProgramer('Albert', 25, 80, 'Python')
    print dir(programer)# 打印对象的属性
    print programer.__dict__
    print type(programer)# 打印对象的类型
    print isinstance(programer, Programer)# 判断programer是否为Programer的子类



运行结果:

['_Programer__weight', '__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_age', 'hobby', 'language', 'name']
{'_age': 25, '_Programer__weight': 80, 'name': 'Albert', 'language': 'Python'}

True



6.类的多态

6.1多态的要素

  • 继承
  • 方法重写

6.2实例代码

# coding:utf-8
class Programer(object):
    hobby = 'Play Computer'

    def __init__(self, name, age, weight):  # 构造方法
        self.name = name
        self._age = age
        self.__weight = weight

    @classmethod
    def get_hobby(cls):
        return cls.hobby

    @property
    def get_weight(self):
        return self.__weight

    def self_introduction(self):
        print 'My Name is %s \nI am %s years old\n' % (self.name, self._age)


class BackendProgramer(Programer):

    def __init__(self, name, age, weight, language):
        super(BackendProgramer, self).__init__(name, age, weight)
        self.language = language

    def self_introduction(self):
        print 'My name is %s \nMy favorite language is %s' % (self.name, self.language)


def introduce(programer):
    if isinstance(programer, Programer):
        programer.self_introduction()


if __name__ == '__main__':

    programer = Programer('Albert', 25, 80,)
    backend_programer = BackendProgramer('Tim', 30, 70, 'Python')
    introduce(programer)
    introduce(backend_programer)


结果:

My Name is Albert 
I am 25 years old

My name is Tim 
My favorite language is Python



7.Magic Method

7.1Magic Method 长什么样

方法名的前后有两个下划线

def __init__(self):

7.2对象实例化的过程

  创建类的对象       --->      初始化对象
def __new__(cls)          def __init__(self):

# coding:utf-8
class Programer(object):
    hobby = 'Play Computer'

    def __new__(cls, *args, **kwargs):
        print 'call __new__ method'
        print args
        return super(Programer, cls).__new__(cls, *args, **kwargs)

    def __init__(self, name, age):  # 构造方法 # 这个注释距离代码两格#号距离注释一格
        print 'call __init__ method'
        self.name = name
        self._age = age


if __name__ == '__main__':

    programer = Programer('Albert', 25)
    print programer.__dict__


结果:

call __new__ method
('Albert', 25)
call __init__ method
{'_age': 25, 'name': 'Albert'}

7.2.1回收

__del__()


8.类与运算符

>>> s == 'test'
>>> s== s
True
>>>dir(s)
['__add__',  '__class__', '__contains__', '__delattr__', '__doc__', '__eq__' ...]

比较运算符

__cmp__(self, other) # 所有比较
__eq__(self, other) # 等于
__lt__(self, other) # 小于
__gt__(self, other) # 大于


__add__(self, other) # 加
__sub__(self, other) # 减
__mul__(self, other) #  乘
__div__(self, other) # 除

逻辑运算符

__or__(self, other) # 或
__and__(self, other) # 和

例子:

# coding:utf-8
class Programer(object):

    def __init__(self, name, age):  # 构造方法
        self.name = name
        if isinstance(age, int):
            self.age = age
        else:
            raise Exception('age must be int')

    def __eq__(self, other):
        if isinstance(other, Programer):
            if self.age == other.age:
                return True
            else:
                return False
        else:
            raise Exception('The type of object must be Programer')

    def __add__(self, other):
        if isinstance(other, Programer):
            return self.age + other.age
        else:
            raise Exception('The type of object must be Programer')


if __name__ == '__main__':

    p1 = Programer('Albert', 25)
    p2 = Programer('Bill', 30)
    print p1 == p2
    print p1 + p2

结果:

False
55

9.类的展现

转换为字符串

__str__ -- 把对象转换成人容易看的字符串
__repr__ -- 把对象转换成机器容易看的字符串
__unicode__

例子:

# coding:utf-8
class Programer(object):

    def __init__(self, name, age):  # 构造方法
        self.name = name
        if isinstance(age, int):
            self.age = age
        else:
            raise Exception('age must be int')

    def __str__(self):
        return '%s is %s years old' % (self.name, self.age)

    def __dir__(self):
        return self.__dict__.keys()


if __name__ == '__main__':

    p = Programer('Albert', 25)
    print p
    print dir(p)


结果:

Albert is 25 years old
['age', 'name']

可以通过魔术方法给属性设置访问控制

__setattr__(self, name, value):

错误示范:

def __setattr__(self, name, value):
    setattr(self, name, value)  # 无限循环

def __setattr__(self, name, value):
    self.__dict__[name] = value  # 正确用法

查询对象属性

__getattr__(self, name);
__getattribute__(self, name):

删除对象属性

__delattr__(self, name):

例子:

# coding:utf-8
class Programer(object):

    def __init__(self, name, age):  # 构造方法
        self.name = name
        self.age = age

    def __getattribute__(self, name):
        # return getattr(self, name) # 无限循环
        # return self.__dict__[name] # 无限循环
        return super(Programer, self).__getattribute__(name) # 正确写法

    def __setattr__(self, name, value):
        # setattr(self, name, value) # 无限循环
        self.__dict__[name] = value # 正确写法


if __name__ == '__main__':

    p = Programer('Albert', 25)
    print p.name


你可能感兴趣的:(Python面向对象)