类和实例
面向过程的编程思路:
std1 = { 'name': 'Michael', 'score': 98 }
std2 = { 'name': 'Bob', 'score': 81 }
def print_score(std):
print('%s: %s' % (std['name'], std['score']))
面向对象编程,简称OOP,是一种程序设计思想。
使用关键字class 创建一个类对象,对比面向对象的编程思路:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
class Student(object):
"""docstring for Student"""
def __init__(self, name,sex):
self.name = name
self.sex=sex
def print_sex(self):
print('%s:%s' % (self.name,self.sex))
运行结果:
image.png在一个类中:
- 类中定义的函数第一个参数永远是self,调用的时候不需要传递;
- 可通过__init__函数在创建实例的时候,将一些必要的属性绑定到对象中。
在__init__函数中:
- 第一个参数永远是self,便是实例对象本身;
- 有了该函数,在实例化的时候必须传入与之匹配的参数。
类Student中的 print_sex函数,实现了打印的功能,我们称之为类的封装,在调用时,我们不需要关心它是怎么实现的这个功能
实例化后的对象,相互之间是独立的。
- 在类中定义私有变量,就是给变量名添加前缀__ 如:__name
- 前后都添加__ 的属于特殊变量,可以直接访问
- 私有变量仍然可以通过_Student__name来访问__name变量
- 私有变量的数据,可以通过封装函数的方式调用和设置
约定大于配置,所有变量前面有_的都不要直接访问
继承和多态
继承定义了Animal父类,和Dog、Cat两个子类,子类自动继承父类的所有。
多态在子类中定义父类已有变量,会被直接覆盖,总是调用子类的run()
class Animal(object):
def run(self):
print('Animal is running...')
class Dog(Animal):
def run(self):
print('Dog is running...')
def eat(self):
print('Eating meat...')
class Cat(Animal):
def run(self):
print('Cat is running...')
在调用过程中,a可以是任意实现了run()函数的对象
def rungo(a):
a.run()
获取对象信息
- type( )
>>> type(123)==int
True
- isinstance( )
可以判断继承关系,优先使用
isinstance(Dog(), Animal)
True
- dir( )
获得一个对象的所有属性和函数
>>> dir('ABC')
['__add__', '__class__',..., '__subclasshook__', 'capitalize', 'casefold',..., 'zfill']
我们可以自定义一个__len__( ) 用于获得类的长度
>>> class MyDog(object):
... def __len__(self):
... return 100
...
>>> dog = MyDog()
>>> len(dog)
100
#等同
>>> dog.__len__( )
可以用于反射的getattr()、setattr()以及hasattr()
from command import MyObject
computer=MyObject()
def run(x):
inp = input('method>')
# 判断是否有这个属性
if hasattr(computer,inp):
# 有就获取然后赋值给新的变量
func = getattr(computer,inp)
print(func())
else:
# 没有我们来set一个
setattr(computer,inp,lambda x:x+1)
func = getattr(computer,inp)
print(func(x))
if __name__ == '__main__':
run(10)
在使用setattr时,第三个参数传入什么类型,inp对象就会生成什么类型
在使用getattr时,能使用对象. 出来的,尽量不使用该函数
实例属性和类属性
实例属性可以看做动态的
类属性可以看做是静态的
优先读取实例属性的值,删除后会自动读取类属性
>>> class Student(object):
... name = 'Student'
...
>>> s = Student() # 创建实例s
>>> s.name = 'Michael' # 给实例绑定name属性
>>> print(s.name) # 由于实例属性优先级比类属性高,因此,它会屏蔽掉类的name属性
Michael
>>> print(Student.name) # 但是类属性并未消失,用Student.name仍然可以访问
Student
>>> del s.name # 如果删除实例的name属性
>>> print(s.name) # 再次调用s.name,由于实例的name属性没有找到,类的name属性就显示出来了
Student
直接类名. 属性 就是一个静态全局的属性
网友评论