python学习面向对象_python学习之面向对象学习

一、什么事面向对象,以及面向对象的优点?

面向过程优缺点:

我们知道面向过程是流水线式的编程,过程就是解决问题的步骤,把大的问题化解成小的模块

面向过程优点: 极大的降低了程序的复杂度

面向过程缺点: 牵一发而动全身, 所以完成一个模块很少改动,否则改动的地方比较多

面向对象优缺点:

面向对象编程的核心是对象,由属性和函数构成

面向对象优点: 解决程序的扩展性,对某个类的修改能反映到整个体系中

类的语法结构:

class 类名:

类体

例子:

class People:

language = 'Chinese'

def func(self):    #self把对象自身传进去

pass

p1 = People

p2 = People

print(p1.language)

print(p2.language)

p1.language = 'english'

print(p1.language)    #输出english

print(p2.language)    #输出english

注: 所有对象共用类的属性,所以p2也输出english

初始化类__init__

例子:

class Garen:

camp='Demacia'

def __init__(self,nickname, aggressivity=58,life_value=456):

self.nickname = nickname

self.aggressivity = aggressivity

self.life_value = life_value

def attack(self,enemy):

enemy.life_value -= self.aggressivity

hero = Garen('garen', 100, 600)    #加括号初始化类对象

print(isinstance(hero, Garen))    #isinstance判断hero是否是类Garen的实例,是则返回True,否则返回False

print(Garen.__name__)   #类的名称

print(Garen.__doc__)    #类的文档字符串

print(Garen.__base__)   #类的第一个父类

print(Garen.__bases__)  #类的所有父类构成的元组

print(Garen.__dict__)   #类的字典属性

print(Garen.__module__) #类定义所在的模块

print(Garen.__class__)  #实例对应的类

将函数绑定到对象上叫做对象的方法,并且会把自身传递给函数作为第一个参数

对象的交互:

class Riven:

camp = 'Noxus'

def __init__(self, nickname, aggressivity=54,life_value=300):

self.nickname = nickname

self.aggressivity = aggressivity

self.life_value = life_value

def attack(self,enemy):

enemy.life_value -= self.aggressivity

r1 = Riven('瑞问问')

print(hero.life_value)

r1.attack(hero)

print(hero.life_value)

print(id(r1.attack))    #id打印函数位置

print(id(Riven.attack))

类有两种属性:数据属性和函数属性,数据属性共享给所有对象。

方法是绑定到所有对象上的,并且对象会传递给函数

创建对象就是创建了一个命名空间,对象会先找自己的命名空间,再找类的命名空间

二、继承

继承是一种创建新类的方式

继承的好处,减少代码冗余,

子类覆盖父类的方法叫做派生

例子:

class ParentClass1:

pass

class ParentClass2:

pass

class SubClass1(ParentClass1):

pass

class SubClass2(ParentClass1,ParentClass2):

pass

print(SubClass1.__bases__)    #打印父类

print(SubClass2.__bases__)    #打印父类

继承关系如图:

0818b9ca8b590ca3270a3433284dd417.png

F->A->E-B->D->C

0818b9ca8b590ca3270a3433284dd417.png

F->D->B-E->C->H->A

派生类

例子:

class Animal:

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

self.name = name

self.age = age

self.sex = sex

def eat(self):

print('eating')

def talk(self):

print('%s 正在叫' %self.name)

class People(Animal):

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

Animal.__init__(self,name,age,sex)

self.education = education

def talk(self):

Animal.talk(self)

print('%s say hello' %self.name)

class Pig(Animal):

pass

class Dog(Animal):

pass

peo1 = People('hyh',20,'male','小学毕业')

pig1 = Pig('zhangsan', 16, 'male')

dog1 = Dog('lisi', 16, 'female')

peo1.talk()

pig1.talk()

dog1.talk()

print(isinstance(peo1, People))    #判断peo1是否是People类,返回True或False

print(isinstance(pig1, Pig))        #继承反映的什么是什么的关系

print(isinstance(dog1, Dog))

通过__dict__获取属性

class Sub:

def __init__(self):

self.bar = 123

def bar(self):

print('Sub.bar')

s = Sub()

print(s.__dict__)

print(s.__dict__['bar'])

组合: 在一个类中,以另外一个类的对象作为数据属性,称为类的组合,组合反映的是什么有什么的关系,

例子:

class People:

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

self.name=name

self.age=age

self.sex=sex

class Date:

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

self.year = year

self.mon = mon

self.day = day

def tell(self):

print('%s-%s-%s' %(self.year,self.mon,self.day))

class Teacher(People):

def __init__(self,name,age,sex,salary,year,mon,day):

self.name = name

self.age = age

self.sex = sex

self.salary = salary

self.birth = Date(year,mon,day)

class Student(People):

def __init__(self,name,age,sex,year,mon,day):

self.name=name

self.age=age

self.sex=sex

self.birth=Date(year,mon,day)

t=Teacher('egon',18,'male',3000,1995,12,31)

t.birth.tell()

定义类模拟接口

例子:

class File:

def read(self):

raise TypeError('类型错误')

def write(self):

raise TypeError('类型错误')

class Txt(File):

def read(self):

print('文本数据的读取方法')

def write(self):

print('文本数据的读取方法')

class Sata(File):

def read(self):

print('硬盘数据的读取方法')

def wirte(self):

print('硬盘数据的读取方法')

class Process(File):

def read(self):

print('进程数据的读取方法')

def write(self):

print('进程数据的读取方法')

p = Process()

p.read()

t = Txt()

d = Sata()

print(isinstance(p, Process))

print(isinstance(t, Txt))

print(isinstance(d, Sata))

注: File类定义功能函数,Txt,Sata,Process分别定义实现函数的方法

调用父类用super方法

例子:

class Foo1:

def test(self):

print("from foo1.test")

class Foo2:

def test(self):

print('from foo2.test')

class Bar(Foo1,Foo2):

def test(self):

super().test()

print('Bar')

b = Bar()

b.test()

三、封装

封装:主要为了保护数据的隐私,而把数据隐藏起来,只能通过接口去访问

类中通过__双下划线来隐藏数据属性和函数属性,含有__x的属性都会变成_类名__x的形式:

Foo:

__x = __test():   ()

(Foo.)

封装实例:

class People:

__country = 'China'

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

self.__name = name

#self._People__name = name

self.__age = age

self.__sex = sex

def tell_info(self):

print('人的名字是:%s, 人的年龄是: %s, 人的性别是: %s' %(self.__name, self.__age, self.__sex))

p = People('alex', 29, 'male')

print(p.__dict__)

p.tell_info()

注: 封装只在定义时检查语法

p.__x = 1

print(p.__x)    #打印1

修改属性接口

class People:

def __init__(self,name,age):

self.__name = name

self.__age = age

def tell_info(self):

print('人的名字是: %s, 人的年龄是: %s' %(self.__name, self.__age))

def set_info(self,x, y):

if not isinstance(x, str):

raise TypeError('名字必须是字符串')

if not isinstance(y, int):

raise TypeError('年龄必须是整数')

self.__name = x

self.__age = y

p = People('alex', 20)

p.tell_info()

p.set_info('hyh', 18)

p.tell_info()

四、特性

property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值

例子:

class People:

def __init__(self,name,weight,height):

self.name=name

self.weight=weight

self.height=height

@property

def bmi(self):

return self.weight / (self.height**2)

p1=People('egon',75,1.85)

print(p1.bmi)

将一个类的函数定义成特性以后,对象再去使用的时候obj.name,根本无法察觉自己的name是

执行了一个函数然后计算出来的,这种特性的使用方式遵循统一访问原则

五、绑定方法与非绑定方法

类中定义的函数分成两大类:

一:绑定方法(绑定给谁,谁来调用就自动将它本身当作第一个参数传入):

1. 绑定到类的方法:用classmethod装饰器装饰的方法。

为类量身定制

类.boud_method(),自动将类当作第一个参数传入

(其实对象也可调用,但仍将类当作第一个参数传入)

2. 绑定到对象的方法:没有被任何装饰器装饰的方法。

为对象量身定制

对象.boud_method(),自动将对象当作第一个参数传入

(属于类的函数,类可以调用,但是必须按照函数的规则来,没有自动传值那么一说)

二:非绑定方法:用staticmethod装饰器装饰的方法

1. 不与类或对象绑定,类和对象都可以调用,但是没有自动传值那么一说。就是一个普通工具而已

注意:与绑定到对象方法区分开,在类中直接定义的函数,没有被任何装饰器装饰的,都是绑定到对象的方法,可不是普通函数,

对象调用该方法会自动传值,而staticmethod装饰的方法,不管谁来调用,都没有自动传值一说。

例子:

import hashlib

import time

class MySQL:

def __init__(self,host,port):

self.id=self.create_id()

self.host=host

self.port=port

@staticmethod

def create_id(): #就是一个普通工具

m=hashlib.md5(str(time.clock()).encode('utf-8'))

return m.hexdigest()

print(MySQL.create_id) # #查看结果为普通函数

conn=MySQL('127.0.0.1',3306)

print(conn.create_id) # #查看结果为普通函数

classmehtod是给类用的,即绑定到类,类在使用时会将类本身当做参数传给类方法的第一个

参数(即便是对象来调用也会将类当作第一个参数传入),python为我们内置了函数classmethod来把类中的函数定义成类方法

例子:

settings.py文件内容

HOST='127.0.0.1'

PORT=3306

import settings

import hashlib

import time

class MySQL:

def __init__(self,host,port):

self.host=host

self.port=port

@classmethod

def from_conf(cls):

print(cls)

return cls(settings.HOST,settings.PORT)

print(MySQL.from_conf) #>

conn=MySQL.from_conf()print(conn.host,conn.port)

conn.from_conf() #对象也可以调用,但是默认传的第一个参数仍然是类

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值