Python初探第三篇-面向对象

Posted ifyoushuai

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python初探第三篇-面向对象相关的知识,希望对你有一定的参考价值。

类和对象

Pyhon中的类和对象与C++中的类和对象有着很大的差别,但是他们都是为了对一个对象的属性和方法进行封装,下面就具体讨论Pyhon的类和对象的使用方法。

 

一,构造函数

 

class Foo:
    def __init__(num):
        self.num = num
f=Foo(1)

  当使用类初始化对象时自动调用__init__()方法。

 

二,类属性和实例属性

  类属性可以通过实例对象或者类本身去调用

class Foo:
    name = "isFoo"
    def __init__(self):
        pass
f = Foo
print(f.name) #isFoo
print(Foo.name)#isFoo

  实例属性可以通过构造函数来绑定,也可以直接绑定

class Foo:
    def __init__(self,name):
        self.name = name

f = Foo("Jack")
f.age = 18
print(f.name) #Jack #实例属性可以通过属性字典来查看 print(f.__dict__) #{‘name‘: ‘Jack‘, ‘age‘: 18}

 注意事项:

  1,类属性只能通过类调用去修改

  2,若用实例区修改类属性,将直接设置一个与类属性同名的实例属性

 

三,继承

  Python3全部是新式类,即类无论是否继承object类,都默认继承它。

class Animal:
    def eat(self):
        print("%s eating sth" % self.name)


class Cat(Animal):
    def __init__(self, name):
        self.name = name


c = Cat("miaomiao")  
c.eat()        # miaomaio eating sth

    子类若没有构造函数,则使用父类的构造函数,若有,即有两种方式来调用父类的构造函数

class Animal:
    def __init__(self,age):
        self.age=age
    def eat(self):
        print("%s eating sth" % self.name)
        
class Cat(Animal):
    def __init__(self, name,age):
        # Animal.__init__(self,age) #first 
        super().__init__(age)       #second
        self.name = name

  抽象类

 

四,组合与重用

  当几个类有着共同的属性时,我们可以将共同的部分抽象出来当做父类,而组合则是一种所有关系,如学校与老师,班级与学生。

class Student:
    def __init__(self,name,age):
        self.name=name
        self.age=age

class class_grade:

    def __init__(self):
        self.li=[]

    def put(self,name,age):
         self.li.append(Student(name, age))

c=class_grade()
c.put("Jack",18)
print(c.li[0].name,c.li[0].age)  #Jack 18

 

五,封装

  封装具有两个特点:

    将属性和方法封装在一个对象中,隐藏细节,仅提供接口;

    具有访问控制;

  第一个特点在前文已经阐述完了,我们来看Python类中的访问控制。

  在Python中并没有真正的限制类的外部或者是子类对类内部数据的访问,而是一种约定,一种隐藏不直接暴露。

  通过双下划线来隐藏

class Foo:
    __N=2
    def __init__(self):
        self.__name="Jack"
    def func(self):
        print(self.__N)  #0
        print(self.__name) #Jack 类的内部可以直接通过名字访问
f=Foo()
f.func()
# print(self.__name) name #‘self‘ is not defined
# print(f.__N)     #‘Foo‘ object has no attribute ‘__N‘
print(f._Foo__N)  #可以通过_类名__变量名 访问 实例属性和函数属性同理  

      这种变形需要注意的问题是:

  1.这种机制也并没有真正意义上限制我们从外部直接访问属性,知道了类名和属性名就可以拼出名字:_类名__属性,然后就可以访问了,如a._A__N,即这种操作并不是严格             意义上的限制外部访问,

  仅仅只是一种语法意义上的变形,主要用来限制外部的直接访问。

  2.变形的过程只在类的定义时发生一次,在定义后的赋值操作,不会变形

 

  那么我们可以用以下方法来给外部提供一个方法,使类外面对私有变量友好访问

     property(特性)

class Foo:
    __N = 2

    def __init__(self):
        self.__name = "Jack"

    @property    #访问
    def name(self):
        return self.__name

    @name.setter    #设置值
    def name(self, value):
        if not isinstance(value, str):
            print("请输入字符串类型")
        else:
            self.__name = value

    @name.deleter    #删除
    def name(self):
        del self.__name


f = Foo()
print(f.name) #像是调用属性,实则调用方法,也符合实际
f.name="Bob"
del f.name

 

  通过实现不同的函数就能实现不同的访问控制

 

六,多态

  我们先回顾一下C++中的多态:父类指针(引用)指向(引用)子类或者父类对象时,会根据实际对象的类型来调用不同的方法。而在python中,由于都是动态数据类型,赋值的时候就是初始化,因此多态更偏向一种代码逻辑而不是语法。

class demo1:
    def display(self):
        print("这是demo1")


class demo2:
    def display(self):
        print("这是demo2")


class demo3:
    def display(self):
        print("这是demo3")


def func(obj):
    obj.display()


if __name__ == __main__:
    d1 = demo1()
    d2 = demo2()
    d3 = demo3()
    # ---调用同一个函数的不同表现形态--
    func(d1)  # 这是demo1
    func(d2)  # 这是demo2
    func(d3)  # 这是demo3

 







以上是关于Python初探第三篇-面向对象的主要内容,如果未能解决你的问题,请参考以下文章

第三篇:函数

javascript面向对象系列第三篇——实现继承的3种形式

python全栈开发第十三篇Python面向对象

Python入门(目录全览)

C++从入门到入土第三篇:类与对象(上篇)

一图胜千言,200行代码图解Python Matplotlib (面向对象法)!