zoukankan      html  css  js  c++  java
  • Python面向对象编程和模块

    在面向对象编程中,你编写表示现实世界中的事物和情景的类,并基于这些类来创建对象。
    编写类时,你定义一大类对象都有的通用行为。基于类创建对象时,每个对象都自动具备这种通用行为,然后根据需要赋予每个对象独特的个性。
    根据类来创建对象被称为实例化,这让你能够使用类的实例。你可以在实例中存储一些信息或者定义一些操作。
    你还可以编写一些类来扩展既有类的功能,让相似的类能够高效地共享代码。

    1. 面向对象编程

    1.1 创建和使用类

    class Car():
    
        def __init__(self, make, model, year):
            self.make = make
            self.model = model
            self.year = year
    
        def get_descriptive_name(self):
            long_name = str(self.year) + ' ' + self.make + ' ' + self.model
            return long_name.title()
    
    my_new_car = Car('audi', 'a4', 2016)
    print(my_new_car.get_descriptive_name())
    
    # 2016 Audi A4
    

    Python中,类的首字母大写。类中的函数称为方法。
    __init__()方法是一个特殊的方法,每当创建实例的时候,Python都会自动运行它。
    这个方法中的形参self必不可少,还必须位于其他形参的前面。每个与类相关联的方法调用都自动传递实参self,它是一个指向实例本身的引用,让实例能够访问类中的属性和方法。

    1.2 访问限制

    # test.py
    class Student(object):
    
        def __init__(self, name, score):
            self.__name = name
            self.__score = score
    
        def print_score(self):
            print('%s: %s' % (self.__name, self.__score))
    		
    
    >>> from test import Student
    >>> student = Student('Bart Simpson', 59)
    >>> student.__name
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: 'Student' object has no attribute '__name'
    

    上面通过实例访问变量__name时报错了。实际上,以两个下划线开头的__name为私有变量。
    不能访问变量__name是因为Python解释器对外把__name改成了_Student__name

    >>> from test import Student
    >>> student = Student('Bart Simpson', 59)
    >>> student._Student__name
    'Bart Simpson'
    

    1.3 继承与多态

    子类继承了其父类的所有属性和方法,同时还可以定义自己的属性和方法。

    1.3.1 继承

    class Car():
    
        def __init__(self, make, model, year):
            self.make = make
            self.model = model
            self.year = year
    
        def get_descriptive_name(self):
            long_name = str(self.year) + ' ' + self.make + ' ' + self.model
            return long_name.title()
    
    		
    class ElectriCar(Car): # 定义子类时,必须在括号内指定父类的名称。
    
        def __init__(self, make, model, year):
            super().__init__(make, model, year) # 调用父类的__init__()方法,从而继承父类的所有属性
    
    my_tesla = ElectriCar('tesla', 'model s', 2016)
    print(my_tesla.get_descriptive_name())
    
    # 2016 Tesla Model S
    
    class ElectriCar(Car):
    
        def __init__(self, make, model, year):
            super().__init__(make, model, year)
            self.battery_size = 70 # 子类的属性
    
        def describe_battery(self): # 子类的方法
            print("This car has a " + str(self.battery_size) + "-kWh battery.")
    
    my_tesla = ElectriCar('tesla', 'model s', 2016)
    print(my_tesla.get_descriptive_name())
    my_tesla.describe_battery()
    
    # 2016 Tesla Model S
    # This car has a 70-kWh battery.
    

    1.3.1 多态

    # 重写父类的方法(多态)
    class Parent:
       def myMethod(self):
          print ('调用父类方法')
     
    class Child(Parent):
       def myMethod(self):
          print ('调用子类方法')
     
    c = Child()
    c.myMethod() # 调用子类方法
    super(Child,c).myMethod() # 调用父类方法
    

    1.3.3 将实例用作属性

    class ElectriCar(Car):
    
        def __init__(self, make, model, year):
            super().__init__(make, model, year)
            self.battery = Battery() # 将实例用作属性
    
    
    class Battery():
    
        def __init__(self, battery_size=70):
            self.battery_size = battery_size
    
        def describe_battery(self):
            print("This car has a " + str(self.battery_size) + "-kWh battery.")
    
    my_tesla = ElectriCar('tesla', 'model s', 2016)
    
    print(my_tesla.get_descriptive_name())
    my_tesla.battery.describe_battery()
    
    # 2016 Tesla Model S
    # This car has a 70-kWh battery.
    

    1.3.4 多重继承

    class people:
        name = ''
        age = 0
        __weight = 0
        #定义构造方法
        def __init__(self,n,a,w):
            self.name = n
            self.age = a
            self.__weight = w
        def speak(self):
            print("%s 说: 我 %d 岁。" %(self.name,self.age))
    
     
    class student(people):
        grade = ''
        def __init__(self,n,a,w,g):
            people.__init__(self,n,a,w)
            self.grade = g
    
        def speak(self):
            print("%s 说: 我 %d 岁了,我在读 %d 年级"%(self.name,self.age,self.grade))
     
    
    class speaker():
        topic = ''
        name = ''
        def __init__(self,n,t):
            self.name = n
            self.topic = t
        def speak(self):
            print("我叫 %s,我是一个演说家,我演讲的主题是 %s"%(self.name,self.topic))
     
    
    class sample(speaker,student):
        a =''
        def __init__(self,n,a,w,g,t):
            student.__init__(self,n,a,w,g)
            speaker.__init__(self,n,t)
     
    
    >>> from test import people, student, speaker, sample
    >>> test = sample("Tim",25,80,4,"Python")
    >>> test.speak() # 调用的是speaker的speak()方法
    我叫 Tim,我是一个演说家,我演讲的主题是 Python
    
    class sample(student,speaker): # 调换了一下括号内父类的顺序
        a =''
        def __init__(self,n,a,w,g,t):
            student.__init__(self,n,a,w,g)
            speaker.__init__(self,n,t)
    
    >>> from test import people, student, speaker, sample
    >>> test = sample("Tim",25,80,4,"Python")
    >>> test.speak()
    Tim 说: 我 25 岁了,我在读 4 年级
    

    1.4 实例属性和类属性

    由于Python是动态语言,根据类创建的实例可以任意绑定属性。

    class Student(object):
        def __init__(self, name):
            self.name = name # 给实例绑定属性
    
    s = Student('Bob')
    s.score = 90 # 给实例绑定属性
    
    class Student(object):
        name = 'Student' # 类属性
    

    实例属性属于各个实例所有,互不干扰。
    类属性属于类所有,所有实例共享一个属性。
    相同名称的实例属性将屏蔽掉类属性,不要对实例属性和类属性使用相同的名字。

    2. 模块

    Python中,模块就是一个后缀名为.py的文件。
    使用模块还可以避免函数名和变量名冲突。但是,名字不要与内置函数名冲突。
    为了避免模块名冲突,Python又引入了按目录来组织模块的方法,称为包。
    请注意,每一个包目录下面都会有一个__init__.py的文件,这个文件是必须存在的,否则,Python就把这个目录当成普通目录,而不是一个包。__init__.py可以是空文件,也可以有Python代码,因为__init__.py本身就是一个模块,而它的模块名就是包目录名。
    自己创建模块时要注意命名,不能和Python自带的模块名称冲突。

    2.1 作用域

    类似__xxx__这样的变量是特殊变量,可以被直接引用。

    # hello.py
    ······
    if __name__ == '__main__': # __name__为特殊变量
        test()
    

    当我们在命令行运行hello模块文件时,Python解释器把一个特殊变量__name__置为__main__,因此这里将执行if语句块里面的代码。而如果我们在其他地方导入hello模块时,将不执行if语句块里面的代码。

    类似_xxx__xxx这样的函数或变量就是非公开的(private),不应该被直接引用。
    Python并没有一种方法可以完全限制访问private函数或变量,但是private函数或变量不应该被直接引用。

    2.2 导入类

    导入单个类

    from car import Car # from 模块名 import 类
    
    my_new_car = Car('audi', 'model s', 2016)
    

    导入多个类

    from car import Car, ElectricCar
    

    导入整个模块

    import car # import 模块名
    
    my_beetle = car.Car('volkswagen', 'beetle', 2016)
    

    导入模块中的所有类

    from car import * # 不推荐
    

    参考资料:

  • 相关阅读:
    面试经验
    java常见面试题目(三)
    java常见面试题目(二)
    java常见面试题目(一)
    Java编程思想:第2章 一切都是对象
    汇编语言:第九章 转移指令的原理
    汇编语言: 实验七 寻址方式在结构化数据访问中的应用
    汇编语言:第八章 数据处理的两个基本问题
    汇编语言:实验六 实践课程中的程序
    汇编语言:第七章 更灵活定位内存地址的方法
  • 原文地址:https://www.cnblogs.com/gzhjj/p/10663367.html
Copyright © 2011-2022 走看看