python基础-面向对象
类和对象:
1.类:是堆某种物种的一种抽象表达,比如人类是我们对于人的一种抽象,他有年龄,身高属性,奔跑,吃饭等行为。
2 对象:对象是对类的一种具体化。比如具体的某个人,它是属于人列这个类的,但是他是个实实在在存在的实体。
class Person(object):
def init(self,name.age):
self.name = name
self.age= age
def eat(self):
print('happy'):
定义一个类:
使用class关键字。object类是python所有类的基类。
class Person(object):
def eat(self)#eat的第一个参数必须是self
print('人这个对象在吃饭:')
p1 = Person()#创建一个对象
p1.eat()
#人这个对象在吃饭
1.定义一个类必须用class关键字,然后继承object类。
2.在类中当以的方法第一个参数必须是self,self代表的是当前这个对象。
3.使用类创建一个对象。对象=类名()
给类添加属性
class Person(object):
def eat(self):
print("happy")
p1 = Person()
p1.name = 'python'
p1.age = '18'
p1.eat()
print(p1.name)
print(p1.age)
#happy
#python
#18
上述书写方式定义方式并不是那么常用。
如果我们创建第二个对象 p2=Person()则此时对象p2不具有name和age的两种属性
为了解决这个问题我们一般实在类的定的时候定义这个类。
class Person(object):
def __init__(self,name,age):#__init__是固定得构造函数名
self.name = name#注意这里的第一个name是定义的一个属性后面的name是穿过来得参数。
self.age = age
def eat(self):
print("我在吃饭")
p1 = Person('pytohn',18)
p1.name = 'python'
print(p1.name,p1.age)
# python 18
函数id可以知道函数的“身份证号码”用于判断是否是同一个对象//形参为对象
class Person(object):
dfe __init__(self,name,age):
self.name = name
self.age = age
print(id(self))
p1 = Person('Python',18)
print(id(p1))
#57634416
#57634416
访问限制
保护属性和方法。
class girl(object):
def __init__(self,age):#定义一个受保护的属性,最好不要访问如果访问也是可以的
self._age=age#一个下划线表示保护类型
girl1 =girl(19)
printf(girl1.age)
私有属性和方法
class Zhanghao(object):
def __init__(self,id)
self.__id= id#两个下划线
p1 = Zhanghao(12323)
print(p1.id)
#'Zhanghao' object has no attribute '__id
私有的方法
class Account(object):
def __init__(self,id,password):
self.a_id = id
self.__password = password
def __account_list(self):
print("我是一个私有函数.")
return ('you know me!')
def get_account_list(self,password):
if password == self.__password:#如果用户输入的密码和之前的相匹配那么久调用私有函数
return self.__account_list()
else:
return None
account = Account('xxx','11111')
print(account.get_account_list('11111'))
#我是一个私有函数
#you know me
3.更多__init__不是私有方法而是特殊的方法。
用对象组装电脑
class CPU(object):
def __init__(self, brand, core, interface):
self.brand = brand
self.core = core
self.interface = interface
class RAM(object):
# 内存类
def __init__(self, brand, size):
self.brand = brand
self.size = size
class Disk(object):
# 硬盘类
def __init__(self, brand, size):
self.brand = brand
self.size = size
class Computer(object):
# 电脑类
def __init__(self, cpu_interface, ram_count, disk_count):
self.cpu_interface = cpu_interface
self.ram_count = ram_count
self.disk_count = disk_count
self.__cpu = None
self.__rams = []
self.__disks = []
def add_cpu(self, cpu):
if cpu.interface == self.cpu_interface:
self.__cpu = cpu
else:
print("cpu型号不,不能安装")
def add_ram(self, ram):
if len(self.__rams) == self.ram_count:
print('内存条已经没有位置安装了')
else:
self.__rams.append(ram)
def add_disk(self, disk):
if len(self.__disks) == self.ram_count:
print("硬盘已经没有位置再安装了")
else:
self.__disks.append(disk)
def run(self):
if not self.__cpu:
print("没有cpu,电脑不能正常运行")
return
elif len(self.__rams) == 0 or len(self.__rams) > self.ram_count:
print('内存安装失败,电脑不能正常运行')
return
elif len(self.__disks) == 0 or len(self.__disks) > self.disk_count:
print("硬盘安装失败,电脑不能正常运行。")
return
else:
print("所有配件都安装完毕,电脑正常运行")
def main():
# 初始化一台电脑
computer = Computer('11211', 2, 2)
# 初始化一个cpu
cpu = CPU('intel', 4, '11211')
# 创建两个内存条
ram1 = RAM('jinshidun', '4G')
ram2 = RAM('jinshidun', '4G')
# 创建两个硬盘
disk1 = Disk('jinshidun', '256G')
disk2 = Disk('jinshidun', '256G')
# 添加一个CPU
computer.add_cpu(cpu)
# 添加一个内存条
computer.add_ram(ram1)
computer.add_ram(ram2)
# 组装硬盘
computer.add_disk(disk1)
computer.add_disk(disk2)
#让电脑运行起来
computer.run()
main()
#所有的配件都组装完成,电脑组装完成
析构函数和引用
class Person(object):
def __init__(self):
self.name='python'
print('这是构造函数')
def greet(self):
print('每天起床第一句:在吗?')
def __del__(self):
print('我是个析构函数')
p = Person()
p.greet()
#这是构造函数
#每天起床第一句:在吗?
#我是个析构函数
程序结束时会自动的调用。
class Person(object):
def __init__(self):
self.fp = open('xxx.txt','w')
def write(self,massage):
self.fp.write(massage)
def __del__(self):
self.fp.close()
'''''
#用于关闭文件
计数引用:
class Person(object):
def __init__(self):
print('我是一个构造函数')
p = Perons()
print(sys.getrefcount(p))
p2 = p
print(sys.getrefcount(p))
继承
class Person(object):
def __init__(self,name,age):
self.name = name
self.age = age
def eat(self):
print('人在吃饭')
def run(self):
print('人在跑步')
class Student(Person):#继承Person的一些特点
pass
s = Student('python',3)
s.eat()
s.run()
print(s.name)
print(s.age)
#同过继承的方式可以直接的使用父类中的函数
重写父类:
有时候父类中的一些属性不应定适用于子类,所以需要重写子类来描写这些不同。
class Perosn(object):
def __init__(self,name,age):
self.name = name
self.age = age
def eat(self):
print('我在吃饭')
class Student(Person):
def __init__(self):
print('学生类')
def eat(self):
print('我在吃饭(学生)')
Student调用调用类的路径,1->查找该函数是否在自己的类中出现,如果没有就去父类中查找
,有些时候自己含有这个函数而需要使用的是父类函数,可以通过子类调用父类的方法。
class Person(object):
def __init__(self,name,age):
self.name = name
self.age = age
print('人类初始化方法')
def eat(self):
print('人吃饭')
class Student(Person):
def __init__(self,name,age):#虽然父类不满足子类的条件但是有一部分也是可以利用的
#因此可以通过子类调用父类方法
super(Student,self).__init__(name,age)#固定格式
print('学生初始化方法')
def eat(self):#如果父类的方法不满足需求可以在子类中重写这个方法,以后对象用同名方法调用
print('学生在吃饭')
def greet(self):
print('myname is %s,my age is %s',(self.name,self.age))
S =Student('python',18)
S.greet()
#人类初始化方法
#学生初始化方法
#my name is python my age is 18
super是一个函数能够返回一个对象利用这个对象可以使用父类的方法。
用法:super(参数1,餐数2) 1 : 类名 2 : self
class Person(object):
def __init__(self,name):
self.__name = name
def greet(self):
print('hello, my name is %s' %self.__name)
class Student(Perosn):
def greet(self):
print('hello,my name is %s' %self.__name)
s1 = Student('pyton')
s1.greet()
#出现错误
子类不能够调用父类的(属性和方法)
可以继呈父类的保护方法。
多继承
class ma(object):
def run(self):
print('马在奔跑')
def eat(self):
print('马在吃草')
class lv(object):
def lamo(self):
print('驴在拉磨')
def eat(self):
print('驴在吃豆子')
class Luozi(ma,lv):
def eat(self):
print('马还是驴呢?')
lz = luozi()
lz.eat()
lz.run()
lz.lamo()
#马还是驴呢?
#马在奔跑
#驴在拉磨
1.子类可以继承两个父类的方法,并且会优先私有自己的方法。
如果子类中没有我们使用的方法而父类中有多个这种方法会怎么样呢
class ma(object):
def run(self):
print('马在奔跑')
def eat(self):
print('马在吃草')
class lv(object):
def lamo(self):
print('驴在拉磨')
def eat(self):
print('驴在吃豆子')
class Luozi(ma,lv):
pass
lz = Luozi()
#print(Luozi.__mro__)
lz.eat()
lz.run()
lz.lamo()
#马在吃草
#马在奔跑
#驴在拉磨
方法调用的顺序已经被保存在一个列表中其中在代码前面的方法被优先的保存起来
通过使用(子类.__mro __*)的方法可以知道使用的顺序
(<class ‘__main __ .Luozi’>, <class ‘main .ma’>, <class ’ main.lv’>, <class ‘object’>)
如果想要使用父类lv中的eat方法需要这样做:
class ma(object):
def run(self):
print('马在奔跑')
def eat(self):
print('马在吃草')
class lv(object):
def lamo(self):
print('驴在拉磨')
def eat(self):
print('驴在吃豆子')
class Luozi(ma,lv):
def eat(self):
#如果不想按照mro的方法执行父类的方法,那么
#可以通过如下方式执行
lv.eat(self):
lz = Luozi()
#print(Luozi.__mro__)
lz.eat()
#lz.run()
#lz.lamo()
#输出为:驴在吃豆子
多态
class Person(object):
def eat(self):
pass
class Student(Person):
def eat(self)
pass
class Teacher(Person):
def eat(self):
pass
def greet(Peron p):
p.eat()
p1 = Person()
greet(p1)
s1 = Studnet()
s1.greet()
#回调用s1中的eat
多态:一种方法可以用于多种数据类型。
class Hero(object):
def __init__(self):
pass
def stroke(self):
pass
class Chengyaojin(Hero):
def stroke(self):
print('程咬金回血大招')
class xiangyu(Hero):
def stroke(self):
print('项羽推人打招')
value = input('请选择英雄')
if value == '1':
hero = Chengyaojin()
else:
hero = xiangyu()
hero.stroke()
#这样当你想要释放大招的时候只管调用这个函数而不用在意英雄是谁
#
class Person(object):
def __init__(self):
self.nume = name
p1 = Peron('python')
p1.age = 18
print(p1.name)
p2 = Perosn('python')
print(p2.name)
print(p2.age)
#'Person' object has no attribute 'age'
实例属性:
绑定到当前属性就是实例属性
实例属性只在当前对象上起作用
类属性:
class Person(object):
country = 'china'
def __init__(self,name):
self.name = name
def greet(self):
#如果对象上没有country属性,那么self.country和Person.country的效果是一样的,都是访问Person的类属性
#如果给对象绑定一个country属性,那么通过self.country访问到的就是这个对象上的属性
#通过Person.country访问到的就是类属性
print('hello my name is %s,i am come form %s' %(self.name,Person.country,self.country))
p1 = Person('python')
p1.country = 'earth'
print(p1.country)
print(Person.country)
#要正确的使用类名可以通过,只能通过类名的方式进行修改
Person.country = 'abc'
print(Person.country)
#earth
#china 可以通过类名直接调用
上述代码便是类属性的定义方式,如果通过对象修改类属性,那么其实不是修改类属性,而是在这个对象上面重新定义了一个名字和相同的实例属性,所以下次再使用该属性时使用的对象的实例属性。
而如果是通过类的方式修改类属性则也会改变
实例方法
class Person(object):
def eat(self):
print('hello')
#这里的eat就是实例方法它只能通过对象来调用而不能通过类来调用。
类方法的调用:
class Person(object):
@classmethod
def greet(cls):
print('python')
Person.greet()
#
1.通过类名调用
2.通过对象调用
class Person(object):
def eat(self):
print('hello word')
#类方法:第一个参数必须是cls,这个代表的是当前这个类
@classmethod
def greet(cls):
cls.country = 'python'
p1 = Person()
p1.greet()
print(Person.country)
person.greet()
p1.greet()
print(Person.country)
#__new__方法:
创建对象 --> 初始化对象
class Car(object):
def __new__(cls,*args,**kwargs):
print('new method')
#return None
#一定要记住,必须在new方法后面返回当前这个类的对象
return super(Car,cls).__new__(cls,*args,**kwargs)
def __init__(self):
print("car in method")
car = Car()
print(car)
#new method
#car in method
#<__main__.Car object at 0x02E56FD0>
三目运算符:
在其他编程语言中,主要用来简化条件判断语句,语法为:条件?满足条件的结果:不满足条件的结果,比如以下案例。
a = 5
b = 2以下代码的意思是:如果a>b则返回1否则返回0
c = a>b?1:0
在python语句不存在三目运算符,但其实可以通过if…else…模拟这种行为,如下例:
a = 5
b = 2
c = 1 if a>b else 0#和上式中的?具有同样的运用
print(c)
#1
set方法:
class Plane(object):
def __init__(slef):
self.alive = True
def set_alive(self,value):
self.alive = value
if vlaue == False:
self.die_action()
def get_vlaue(self):
if not self.value:
self.cancel_schedule()
def set_score(self,value):
self.score = value
self._update_score_brand(value)
def _update_score_brand(self,value):
print('积分榜的值为: %d' % value)
def die_action(self):
print('飞机被撞状态')
p = Plane()
hit = True
if hit:
p.set_alive(False)
#set_alive方法为想要的值
问题分析:程序中每需要一个信息我们都要set和get方法如果有成百上千的问题则会是非的麻烦为了解决这一问题我们引入了propety装饰器。
propety装饰器
class Plane(object):
def __init__(slef):
self.alive = True
#alive设置为属性以后调用temp = p.alive(get方法)就会执行这个代码
@property
def alive(self):
if not self.value:
self.cancel_schedule()
return self.alive
@alive.setter
def alive(self,value):
self.alive = value#会调用自己,
#可以通过修改alive的名称解决
if vlaue == False:
self.die_action()
def set_score(self,value):
self.score = value
self._update_score_brand(value)
def _update_score_brand(self,value):
print('积分榜的值为: %d' % value)
def die_action(self):
print('飞机被撞状态')
p = Plane()
hit = True
if hit:
p.alive = False#执行set方法
temp = P.alive#执行get方法