折叠

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'
posted @ 2021-03-16 20:09  Coverpast  阅读(160)  评论(0编辑  收藏  举报