python面向什么编程_Python之面向对象编程

初识类

类是用来描述具有相同属性和方法的对象的集合。对象是具体存在的,而类是一种抽象概念。在程序中遵循先定义类再调用类的顺序。类的名字是采用驼峰体的,类在定义阶段就会立刻执行类体内代码,将产生的名字存放在类的名称空间中,可以用__dict__查看类的名称空间,将以字典形式返回结果。

类分为父类和子类。父类又称为基类或超类,子类又称为派生类。类有两种属性:数据属性和函数属性(函数是没有被任何装饰器装饰的)。类的数据属性是直接对象所有共享的,类的函数属性是绑定给对象用的,绑定给不同的对象就是不同的绑定方法。

classStudent:

#定义私有属性,外部无法直接访问

n=0

#__init__()构造方法

#self代表类的实例

#def定义方法,类方法的第一个参数必须是用来代表类的实例的def __init__(self,name,age,gender):

self.name=name#类对象的属性引用

self.age=age

self.gender=gender

Student.n+=1school='红太阳'

deflearn(self):return '%s is learning'%self.name

#obj.class指向类

stu1=Student('aa',19,'female')#类对象的实例化#print(stu1.n)#print(stu1.learn)##>#print(stu1.learn())

stu2=Student('bb',23,'male')#print(stu2.n)#print(stu2.learn)##>

#print(id(Student.n),Student.n)#print(id(stu1.n),stu1.n)#print(id(stu2.n),stu2.n)##同id

#Student.n=1#print(id(Student.n),Student.n)#print(id(stu1.n),stu1.n)#print(id(stu2.n),stu2.n)#都随着Student.n变化而变

#stu1.n=1#print(id(Student.n),Student.n)#print(id(stu1.n),stu1.n)#1345678816 1#print(id(stu2.n),stu2.n)#只有stu1变化,其他都不变

类的实例化就是调用类产生对象的过程,实例对象就是类的实例化的结果。对象除了共有的属性和方法之外,应该还有其特有的,这样类实例化结果的对象就不是一模一样的了。要使对象就有其特征,就要在类体内定义一个__init__函数,该函数在调用类时自动触发执行。

调用类的过程将发生三件事:

一是产生空对象;

二是自动触发类体内的__init__函数;

三是将空对象连同调用类时括号内的参数一起传给__init__函数。

类的使用:

1.必须遵循函数的参数规则

2.类中定义的函数主要是给对象使用的,而且是绑定到对象的。虽然所有对象的指向都是相同的功能,但是绑定到不同对象就是不同的绑定方法。绑定到对象的特殊之处就在于绑定谁就由谁调用,谁调用就将谁本身当做第一个参数(self)传给方法,即自动传值。

对象间的交互

classDog:def __init__(self,name,d_type,aggressivity,life_value):

self.name=name

self.d_type=d_type

self.aggressivity=aggressivity

self.life_value=life_valuedefbite(self,enemy):

enemy.life_value-=self.aggressivityprint('''狗[%s]咬人[%s]

人掉血[%s]

人的生命值还剩[%s]'''%(self.name,enemy.name,self.aggressivity,enemy.life_value))

dog1= Dog('旺财', '中华田园犬', 50, 60)classPeople:def __init__(self,name,aggressivity,life_value=100):

self.name=name

self.aggressivity=aggressivity

self.life_value=life_valuedefbite(self,enemy):

enemy.life_value-=self.aggressivityprint('''人[%s]咬狗[%s]

狗掉血[%s]

狗的生命值还剩[%s]''' %(self.name, enemy.name, self.aggressivity, enemy.life_value))

people1=People('aa',30)

people1.bite(dog1)

继承和派生

继承就是类与类之间的关系,是创建类的一种方式,继承的 目的就是减少代码冗余。子类会遗传父类的属性,子类可以继承一个或多个父类。

寻找继承关系需要先抽象再继承。

属性查找是现从子类自己查找,找不到再去父类查找。

派生就是子类定义 自己的新属性,如果是与父类的属性同名,以子类 自己的为准。在子类派生的 新方法中重用父类功能的方式:一是指名道姓地调用,这种方式与继承关系是无关的 ,与调用普通函数是一样的;二是通过执行super()得到返回值,该返回值是一个 特殊对象,该对象专门用来调用mro()列表从当前的查找位置往后查找下一个类的属性或方法。第二种方法是严格遵循继承关系的。

组合

1.组合是什么?

组合是用于描述一个对象拥有的属性,该属性来自于另一个类。

2.组合怎么用?

class School:

school='red hair'

def __init__(self,name,age,gender):

self.name=name

self.age=age

self.gender=gender

class Date:

def __init__(self,year,mon,day):

self.year = year

self.mon = mon

self.day = day

def tell_birth(self):

print('''

==========

year [%s]

month [%s]

day [%s]

'''%(self.year,self.mon,self.day))

class Teacher(School):

def __init__(self,name,age,gender,level,salary):

super(Teacher,self).__init__(name,age,gender)#用super()重用父类

self.level=level

self.salary=salary

self.courses=[]

def change_score(self):

print('teacher is changing score')

def tell_course_info(self):

print(('teacher [%s] has course:'%self.name).center(50,'='))

for course_obj in self.courses:

course_obj.info()#组合

class Student(School):

def __init__(self,name,age,gender,grade):

super(Student,self).__init__(name,age,gender)

self.grade=grade

self.courses=[]

def choose(self):

print('student [%s] choose course'%self.name)

def tell_course_info(self):

print(('student [%s] learn course:'%self.name).center(50,'='))

for course_obj in self.courses:

course_obj.info()

class Course:

def __init__(self,cname,period,price):

self.cname=cname

self.period=period

self.price=price

def info(self):

print('''

========course info========

course_name <%s>

course_period <%s>

course_price <%s>

'''%(self.cname,self.period,self.price))

t1=Teacher('aa',20,'female',9,3.1)

# t1.birth=Date(1998,12,12)

# t1.birth.tell_birth()

s1=Student('bb',16,'male','python')

# s1.birth=Date(2002,12,12)

# s1.birth.tell_birth()

python=Course('python','5mons',20000)

linux=Course('linux','5mons',20000)

go=Course('Go','5mons',25000)

# t1.course=python

# s1.course=python

# t1.course.tell_course_info()

t1.courses.append(python)

t1.courses.append(linux)

print(t1.courses)

for course_obj in t1.courses:

course_obj.info()

# t1.tell_course_info()

s1.courses.append(go)

s1.courses.append(python)

s1.tell_course_info()

封装

1.封装是什么?

封装从字面意思上看是隐藏,但是又与隐藏有所不同,封装是对外隐藏,对内公开。

封装数据属性:把数据属性封装起来,将需要的开辟接口给外部使用者用。其好处是添加控制逻辑,从而控制访问者对属性的操作,起到隔离复杂性的效果。

2.封装如何实现隐藏?

在属性名前面加__开头,但是不是以__结尾的

class ATM:

def __insert_card(self):

print('insert your card')

def __transfer(self):

print('transfer')

def __with_draw(self):

print('withdraw')

def __repay(self):

print('repay')

def __check_flow(self):

print('check your bank flow')

def run(self):

self.__insert_card()

self.__transfer()

self.__with_draw()

self.__repay()

self.__check_flow()

obj=ATM()

obj.run()

3.封装要注意的三个点:

(1)为一个属性加__开头会在属性定义阶段将属性名变形,是一种语法上的变形

(2)这种语法上变形只在定义阶段发生一次,定义之后新增的属性即使是以__开头也不会变形

(3)如果父类不想属性被子类的覆盖就可以给该属性加__开头

多态

1.多态是什么?

多态就是同一属性的多种形态

2.多态的特性?

可以在不考虑对象具体类型的前提下直接使用对象下的方法

3.使用多态的好处?

(1)增加程序的灵活性

(2)增加了程序的可扩展性

import abc #abstractclass抽象类

class Animal(metaclass=abc.ABCMeta):#抽象基类,抽象基类本身不能再实例化

@abc.abstractmethod

def eat(self):

pass

@abc.abstractmethod

def bark(self):

pass

class Cat(Animal):

def eat(self):

print('cat eatting')

def bark(self):

print('cat bark')

class Dog(Animal):

def eat(self):

print('dog eatting')

def bark(self):

print('dog bark')

dog=Dog()

cat=Cat()

cat.eat()

def EAT(obj):

obj.bark()

EAT(cat)

鸭子类型

Python崇尚鸭子类型,即‘如果看起来像、叫声像而且走起路来像鸭子,那么它就是鸭子’

python程序员通常根据这种行为来编写程序。例如,如果想编写现有对象的自定义版本,可以继承该对象

也可以创建一个外观和行为像,但与它无任何关系的全新对象,后者通常用于保存程序组件的松耦合度。

反射

通过字符串来操作类与对象的属性,这种操作称为反射;反射也是内置函数

下述四个函数是专门用来操作类与对象属性的

classPeople:

country="China"

def __init__(self,name):

self.name=namedeftell(self):print('%s is aaa' %self.name)

obj=People('egon')

1、hasattr

print(hasattr(People,'country')) #可用来操纵类 # print('country' in People.__dict__)

print(hasattr(obj,'name')) #可用来操纵对象

print(hasattr(obj,'country'))print(hasattr(obj,'tell'))

2、getattr

print(getattr(People,'country1',None)) #如果没有返回None;若不写,没有报错

f=getattr(obj,'tell',None) #obj.tell

f() #obj.tell()

3、setattr

setattr(People,'x',111) #People.x=111

print(People.x)

setattr(obj,"age",18) #obj.age=18

print(obj.__dict__)

4、delattr

delattr(People,"country") #del People.country

print(People.__dict__)

delattr(obj,"name") #del obj.name

print(obj.__dict__)#用户用input输入了字符串形式的指令,可以被反射以操纵类和对象的属性

classFoo:defrun(self):whileTrue:

cmd=input('cmd>>:').strip()ifhasattr(self,cmd):

func=getattr(self,cmd)

func()defdownload(self):print('download....')defupload(self):print('upload...')

obj=Foo()

obj.run()

三、__str__方法

__xxx__是满足一定条件时自动触发

__str__ 当打印对象时自动触发,可用来定制打印格式

classPeople:def __init__(self,name,age,sex):

self.name=name

self.age=age

self.sex=sexdef __str__(self):return '<名字:%s 年龄:%s 性别:%s>' %(self.name,self.age,self.sex)

obj=People('egon',18,'male')print(obj) #print(obj.__str__()),若没有__str__,返回一个内存地址(原生状态)

l=list([1,2,3])print(l) #[1, 2, 3], python帮忙优化的,否则返回一个内存地址

四、__del__方法

__del__在删除对象时自动触发

importtimeclassPeople:def __init__(self,name,age,sex):

self.name=name

self.age=age

self.sex=sexdef __del__(self): #在对象被删除的条件下,自动执行

print('__del__')

obj=People('egon',18,'male')del obj #obj.__del__() #若没有这一行,睡2s后会自动触发__del__,因为程序结束前会删除对象(清除资源)

time.sleep(2)

__del__的主要用途是回收系统资源

classMysql:def __init__(self,ip,port):

self.ip=ip

self.port=port

self.conn=connect(ip,port) #申请系统资源, 此行为伪代码

def __del__(self):

self.conn.close()#回收系统资源

obj=Mysql('1.1.1.1',3306)classMyOpen:def __init__(self,filepath,mode="r",encoding="utf-8"):

self.filepath=filepath

self.mode=mode

self.encoding=encoding

self.fobj=open(filepath,mode=mode,encoding=encoding)def __str__(self):

msg="""filepath:%s

mode:%s

encoding:%s""" %(self.filepath,self.mode,self.encoding)returnmsgdef __del__(self):

self.fobj.close()#回收系统资源

f=MyOpen('aaa.py',mode='r',encoding='utf-8')print(f.filepath,f.mode,f.encoding)print(f)print(f.fobj)

res=f.fobj.read()print(res)

以下四个皆为绑定对象的方法,在满足一定条件时,自动触发

__init__

__str__

__del__

__call__

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值