zoukankan      html  css  js  c++  java
  • Python基础语法快速复习-面对对象编程

    1 类和实例

    类的定义方式:class关键字

    class Student(object):
        pass
    

    class后的Student表示类名,object表示所有类都会继承的类

    下面根据类创建实例:类名+()实现

    bart = Student()
    print(bart)
    print(Student)
    
    <__main__.Student object at 0x000001791DA54C70>
    <class '__main__.Student'>
    

    bart指向Student的实例,at后为内存地址。

    给实例bart绑定name属性

    bart.name = 'Bart Simpson'
    bart.name
    
    'Bart Simpson'
    

    通过定义一个特殊的__init__方法,在创建实例的时候,就把name,score等属性绑上去:

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

    self表示创建的实例本身。用init方法创建实例之后,不能传入空的参数,必须与init方法中的参数匹配

    bart = Student('Bart Simpson',59)
    print(bart.name)
    print(bart.score)
    
    Bart Simpson
    59
    

    在类中定义函数和普通函数的区别是:第一个参数永远是实例变量self且在调用时不用传递该参数。

    1.1 数据封装

    直接在Student类的内部定义访问数据的函数

    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))
    
    bart = Student('Bart Simpson',59)
    bart.print_score()
    
    Bart Simpson:59
    

    2 访问限制

    如果要让内部属性不被外部访问,可以在属性的名称前加上两个下划线__(变为私有属性/变量)

    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))
            
    bart = Student('Bart Simpson',59)
    bart.__name
    
    ---------------------------------------------------------------------------
    
    AttributeError                            Traceback (most recent call last)
    
    <ipython-input-12-f1e304b30ef3> in <module>
          7 
          8 bart = Student('Bart Simpson',59)
    ----> 9 bart.__name
    
    
    AttributeError: 'Student' object has no attribute '__name'
    

    外部代码需要获取name和score

    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))
            
        def get_name(self):
            return self.__name
        
        def get_score(self):
            return self.__score
        #修改分数
        def set_score(self, score):
            if 0 <= score <= 100:
                self.__score = score
            else:
                raise ValueError('bad score')
    

    变量名类似__ xxx __ 的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是private变量,所以,不能用 __ name __ 、__ score __ 这样的变量名。

    3 继承和多态

    定义一个class时,可以从现有class继承,新的class称为子类,被继承的class称为基类、父类或超类。

    定义一个名为Animal的class,内部有run()方法可以直接进行打印。

    class Animal(object):
        def run(self):
            print('Animal is running...')
    

    编写Dog和Cat直接继承父类Animal的全部功能

    class Dog(Animal):
        pass
    class Cat(Animal):
        pass
    
    dog = Dog()
    dog.run()
    
    cat = Cat()
    cat.run()
    
    Animal is running...
    Animal is running...
    

    当子类和父类存在相同方法的时候,子类的方法会覆盖父类的方法,在代码运行的时候总会调用子类的方法。这就是多态。

    下面我们利用多态修改run()方法。

    class Dog(Animal):
        def run(self):
            print("Dog is running")
    
    class Cat(Animal):
        def run(self):
            print('Cat is running')
            
    dog = Dog()
    dog.run()
    
    cat = Cat()
    cat.run()
    
    Dog is running
    Cat is running
    

    理解多态的好处:编写一个函数,函数接受一个Animal类型的变量

    def run_twice(animal):
        animal.run()
        animal.run()
    
    run_twice(Animal())
    
    Animal is running...
    Animal is running...
    
    run_twice(Dog())
    
    Dog is running
    Dog is running
    

    再定义一个Tortoise类型,从Animal派生:

    class Tortoise(Animal):
        def run(self):
            print('Tortoise is running slowly...')
    
    run_twice(Tortoise())
    
    Tortoise is running slowly...
    Tortoise is running slowly...
    

    新增一个Animal的子类,不必对run_twice()做任何修改,实际上,任何依赖Animal作为参数的函数或者方法都可以不加修改地正常运行,原因就在于多态。

    “开闭”原则:调用方只管调用,不管细节,而当我们新增一种Animal的子类时,只要确保run()方法编写正确,不用管原来的代码是如何调用的。

    4 获取对象信息

    4.1 使用type()判断对象类型

    #基本类型的判断
    print(type(123))
    print(type('str'))
    print(type(None))
    
    #指向函数或者类的变量
    print(type(abs))
    
    <class 'int'>
    <class 'str'>
    <class 'NoneType'>
    <class 'builtin_function_or_method'>
    

    4.2 使用isinstance判断class类型

    class Husky(object):
        pass
    
    #先创建3种类型的对象
    a = Animal()
    d = Dog()
    h = Husky()
    
    #进行判断
    isinstance(h,Husky)
    
    True
    
    isinstance(h,Dog)
    
    False
    

    能用type()判断的基本类型也可以使用isinstance进行判断

    print(isinstance('a',str))
    print(isinstance(123,int))
    print(isinstance(b'a',bytes))
    
    True
    True
    True
    

    判断变量是否为某些类型中的一种

    isinstance([1,2,3],(list,tuple))
    
    True
    

    4.3 使用dir()获取一个对象的所有属性和方法。

    #使用dir函数作用于对象,返回包含多个字符串的list
    #获得一个字符串对象的所有属性和方法
    dir('ABC')
    
    ['__add__',
     '__class__',
     '__contains__',
     '__delattr__',
     '__dir__',
     '__doc__',
     '__eq__',
     '__format__',
     '__ge__',
     '__getattribute__',
     '__getitem__',
     '__getnewargs__',
     '__gt__',
     '__hash__',
     '__init__',
     '__init_subclass__',
     '__iter__',
     '__le__',
     '__len__',
     '__lt__',
     '__mod__',
     '__mul__',
     '__ne__',
     '__new__',
     '__reduce__',
     '__reduce_ex__',
     '__repr__',
     '__rmod__',
     '__rmul__',
     '__setattr__',
     '__sizeof__',
     '__str__',
     '__subclasshook__',
     'capitalize',
     'casefold',
     'center',
     'count',
     'encode',
     'endswith',
     'expandtabs',
     'find',
     'format',
     'format_map',
     'index',
     'isalnum',
     'isalpha',
     'isascii',
     'isdecimal',
     'isdigit',
     'isidentifier',
     'islower',
     'isnumeric',
     'isprintable',
     'isspace',
     'istitle',
     'isupper',
     'join',
     'ljust',
     'lower',
     'lstrip',
     'maketrans',
     'partition',
     'replace',
     'rfind',
     'rindex',
     'rjust',
     'rpartition',
     'rsplit',
     'rstrip',
     'split',
     'splitlines',
     'startswith',
     'strip',
     'swapcase',
     'title',
     'translate',
     'upper',
     'zfill']
    

    仅仅列出class的属性和方法是不够的,配合getattr()、setattr()以及hasattr()可以直接操作对象的状态

    class MyObject(object):
        def __init__(self):
            self.x=9
        def power(self):
            return self.x *self.x
    obj = MyObject()
    
    #测试对象属性
    #判断属性x是否存在
    print(hasattr(obj,'x'))
    print(obj.x)
    print(hasattr(obj,'y'))
    #设置属性y
    print(setattr(obj,'y',19))
    print(getattr(obj,'y'))
    obj.y
    
    True
    9
    False
    None
    19
    
    
    
    
    
    19
    

    4.4 实例属性和类属性

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

    给实例绑定属性的方法通过实例变量或者通过self变量。

    class Student(object):
        def __init__(self,name):
            self.name = name
    s = Student('Bob')
    s.score = 90
    

    在class中直接定义的属性叫做类属性,归类所有,类的所有实例都可以访问到。

    class Student(object):
        name = 'Student'
    
  • 相关阅读:
    第八场 hdu 6136 Death Podracing(dfs+思维)
    第九场 hdu 6162 Ch’s gift(树链剖分+线段树)
    树链剖分 模板
    CodeForces
    第十场 hdu 6172 Array Challenge(矩阵快速幂)
    第十场 hdu 6171 Admiral(双向bfs找交点)
    CodeForces
    第十场 hdu 6178 (bfs)
    第十场 hdu 6180 Schedule (multiset)/(思维)
    第八场 hdu 6143 Killer Names(思维题)
  • 原文地址:https://www.cnblogs.com/MurasameLory-chenyulong/p/14545559.html
Copyright © 2011-2022 走看看