类和对象
类属性和对象属性
当实例化对象的时候,加了新的属性并赋值,会优先使用对象属性(即使类中也有同样的属性),当对象属性没做改变时,使用类属性。
类中self的作用
类中的self其实就是指类本身。
cat duixiang3.py
#!/usr/bin/env pthon3
# -*- coding: UTF-8 -*-
class Phone:
def call(self):
print(self)
p=Phone()
print(p.call)
[root@ceph01 python]# python3 duixiang3.py
<bound method Phone.call of <__main__.Phone object at 0x7f31e7e450f0>>
改变类属性
cat duixiang1.py
#!/usr/bin/env pthon3
# -*- coding: UTF-8 -*-
class Phone:
#类属性
brand='xiaomi'
price=4999
type='mate80'
def call(self):
print("手机品牌是{}".format(self.brand))
phone1=Phone()
phone1.brand='华为'
phone2=Phone()
phone2.note='iphone'
phone1.call()
phone2.call()
python3 duixiang1.py
手机品牌是华为
手机品牌是xiaomi
python对象方法
定义一个类
#!/usr/bin/env python3
#coding:utf8
class Phone:
brand='xiaomi'
price=4999
type='mate80'
def call(self):
print('正在打电话')
print('留言:',self.note)
phone1=Phone()
phone1.note='wo shi phone1 de note'
phone2=Phone()
phone2.note='wo shi phone2 de note'
phone1.call()
phone2.call()
输出
python3 class.py
正在打电话
留言: wo shi phone1 de note
正在打电话
留言: wo shi phone2 de note
python对象
cat >duixiang2.py<<EOF
#!/usr/bin/env pthon3
# -*- coding: UTF-8 -*-
class Phone:
brand='xiaomi'
price=4999
type='mate80'
def call(self):
print('self------',self)
print('正在访问通讯录')
for person in self.address_book:
print(person.items())
print('正在打电话')
print('留言',self.note)
phone1=Phone()
phone1.note='wo shi phone1 de note'
phone1.address_book=[{"123456784449":'ein'},{'2489328928392':'newton'}]
phone2=Phone()
phone2.note='wo shi phone2 de note'
phone2.address_book=[{"123434445439":'jia'},{'24893289356792':'zhen'}]
phone1.call()
phone2.call()
EOF
执行代码
python3 duixiang2.py
self------ <__main__.Phone object at 0x7f237a8d14e0>
正在访问通讯录
dict_items([('123456784449', 'ein')])
dict_items([('2489328928392', 'newton')])
正在打电话
留言 wo shi phone1 de note
self------ <__main__.Phone object at 0x7f237a8d1518>
正在访问通讯录
dict_items([('123434445439', 'jia')])
dict_items([('24893289356792', 'zhen')])
正在打电话
留言 wo shi phone2 de note
cat类
cat cat.py
#!/usr/bin/env pthon
# -*-coding:UTF-8 -*-
class Cat:
type='猫'
def __init__(self,nickname,age,color):
self.nickname=nickname
self.age=age
self.color=color
def eat(self,food):
print('{}喜欢吃{}'.format(self.nickname,food))
def catch_mouse(self,color,weight):
print('{}抓了一只{}kg的,{}的大老鼠'.format(self.nickname,weight,color))
def sleep(self,hour):
if hour<5:
print('乖乖,继续睡觉吧')
else:
print('赶快起床,出去抓老鼠')
def show(self):
print('猫的详细信息')
print(self.nickname,self.age,self.color)
cat1=Cat('花花','2','灰色')
cat1.catch_mouse('黑色','2')
cat1.sleep(8)
cat1.eat('小金鱼')
python cat.py
花花抓了一只2kg的,黑色的大老鼠
赶快起床,出去抓老鼠
花花喜欢吃小金鱼
类方法
cat dog.py
#!/usr/bin/env pthon
# -*-coding:UTF-8 -*-
class Dog:
def __init__(self,nickname):
self.nickname=nickname
def run(self):
print('{}在原子里跑来跑去'.format(self.nickname))
@classmethod
def test(cls):
print(cls)
print(cls.nickname)
d=Dog('大黄')
d.run()
d.test()
python dog.py
大黄在原子里跑来跑去
__main__.Dog
Traceback (most recent call last):
File "dog.py", line 15, in <module>
d.test()
File "dog.py", line 11, in test
print(cls.nickname)
AttributeError: class Dog has no attribute 'nickname'
类属性
cat> dog.py <<EOF
#!/usr/bin/env pthon
# -*-coding:UTF-8 -*-
class Dog:
nickname='小黑'
def __init__(self,nickname):
self.nickname=nickname
def run(self):
print('{}在原子里跑来跑去'.format(self.nickname))
@classmethod
def test(cls):
print(cls)
print(cls.nickname)
Dog.nickname='大黄'
Dog.test()
EOF
python dog.py
__main__.Dog
大黄
类中函数调函数
cat dog.py
#!/usr/bin/env pthon
# -*-coding:UTF-8 -*-
class Dog:
nickname='小黑'
def __init__(self,nickname):
self.nickname=nickname
def run(self):
print('{}在原子里跑来跑去'.format(self.nickname))
def eat(self):
print('吃饭')
self.run()
@classmethod
def test(cls):
print(cls)
print(cls.nickname)
d=Dog('大黄')
d.eat()
Dog.nickname='大黄'
Dog.test()
python dog.py
吃饭
大黄在原子里跑来跑去
__main__.Dog
大黄
私有属性
先看一个例子
cat >class.py<<EOF
#!/usr/bin/env pthon
# -*-coding:UTF-8 -*-
#!/usr/bin/env pthon
# -*-coding:UTF-8 -*-
class Person:
age=18
def show(self):
print(Person.age)
p=Person()
p.show()
print('原值{}'.format(Person.age))
EOF
python class.py
18
原值18
私有化属性
cat >class.py<<EOF
#!/usr/bin/env pthon
# -*-coding:UTF-8 -*-
#!/usr/bin/env pthon
# -*-coding:UTF-8 -*-
class Person:
__age=18
def show(self):
print(Person.__age)
p=Person()
p.show()
print('原值{}'.format(Person.__age))
EOF
python class.py
18
Traceback (most recent call last):
File "class.py", line 12, in <module>
print('原值{}'.format(Person.__age))
AttributeError: class Person has no attribute '__age'
使用类方法修改私有属性
cat >class2.py<<EOF
#!/usr/bin/env pthon
# -*-coding:UTF-8 -*-
class Person:
__age=18
def show(self):
print(Person.__age)
@classmethod
def update_age(self):
self.__age=20
print('类方法')
print('修改后的年龄是{}'.format(self.__age))
Person.update_age()
EOF
[root@tecent python]# python class2.py
类方法
修改后的年龄是20
静态方法
很类似类方法
1、需要装饰器@staticmethod
2、静态方法无需调用传递参数(cls,self)
3、也只能访问类的属性和方法,对象的是无法访问的
4、加载时机同类方法
cat >class3.py<<EOF
#!/usr/bin/env pthon
# -*-coding:UTF-8 -*-
class Person:
__age=18
def __init__(self,name):
self.name=name
@staticmethod
def test():
print('静态方法')
#print(self.name) 无法调用对象方法
print(Person.__age)
Person.test()
EOF
python class3.py
静态方法
18
类方法和静态方法总结
不同:
1、装饰器不同
2、类方法是有参数的,静态方法没有参数
相同:
1、只能访问类的属性和方法
2、都可以通过类名调用访问
3、都可以在创建对象之前使用,因为不依赖与对象
普通方法与类和静态方法的区别:
不同:
1、没有装饰器
2、普通方法永远是要依赖于对象的,因为每个普通方法都有一个self
3、只有创建了对象才可以调用普通方法,否则无法调用。
魔术方法
python魔术方法__init__
cat >duixiang2.py << EOF
#!/usr/bin/env pthon
# -*- coding: UTF-8 -*-
class Phone:
def __init__(self):
print ("init")
phone1=Phone()
phone2=Phone()
EOF
执行代码
注意:不调用也会执行__init__方法
python duixiang2.py
init
init
init方法
cat >init.py<<EOF
#!/usr/bin/env pthon
# -*- coding: UTF-8 -*-
class Person:
name='张三'
def __init__(self):
self.name='zhangshan'
self.age=18
def eat(self):
print('{}正在吃红烧肉'.format(self.name))
p1 = Person()
#p1.name='李四'
p1.eat()
EOF
python init.py
zhangshan正在吃红烧肉
init方法
cat >init.py<<EOF
#!/usr/bin/env pthon
# -*- coding: UTF-8 -*-
class Person:
name='张三'
def __init__(self):
self.name='zhangshan'
self.age=18
def eat(self):
print('{}正在吃红烧肉'.format(self.name))
p1 = Person()
p1.name='李四'
p1.eat()
EOF
python init.py
李四正在吃红烧肉
init方法
cat >init.py<<EOF
#!/usr/bin/env pthon
# -*- coding: UTF-8 -*-
class Person:
name='张三'
def __init__(self):
self.name='zhangshan'
self.age=18
def eat(self):
print('{}{}岁正在吃红烧肉'.format(self.name,self.age))
p1 = Person()
p1.name='李四'
p1.eat()
EOF
python init.py
李四18岁正在吃红烧肉
对象传参(报错)
cat init3.py
#!/usr/bin/env pthon
# -*- coding: UTF-8 -*-
class Person:
name='张三'
def eat(self,name,age):
self.name=name
self.age=age
print('{}{}岁正在吃红烧肉'.format(self.name,self.age))
p1 = Person('张三','18')
p1.eat()
python init3.py
Traceback (most recent call last):
File "init3.py", line 10, in <module>
p1 = Person('张三','18')
TypeError: this constructor takes no arguments
带参数的init
cat >init2.py<<EOF
#!/usr/bin/env pthon
# -*- coding: UTF-8 -*-
class Person:
name='张三'
def __init__(self,name,age):
self.name=name
self.age=age
def eat(self):
print('{}{}岁正在吃红烧肉'.format(self.name,self.age))
p1 = Person('张三','18')
p1.eat()
EOF
python init2.py
张三18岁正在吃红烧肉
可传参的init(注意参数部分)
cat init3.py
#!/usr/bin/env pthon
# -*-coding:UTF-8 -*-
class Person:
name='张三'
def __init__(self,n,age):
self.name=n
self.age=age
def eat(self):
print('{}{}岁正在吃红烧肉'.format(self.name,self.age))
p1 = Person('张三','18')
p1.eat()
python init3.py
张三18岁正在吃红烧肉
init
初始化魔方方法
触发时机:初始化对象时触发(不是实例化触发,但是和实例化在一个操作中)
参数:至少有一个self,接收对象
返回值:无
作用:初始化对象的成员
注意:使用该方式初始化的成员都是直接写入对象当中,类中无法具有
new
实例化魔方方法
触发时机:在实例化对象时触发
参数:至少一个cls接收当前类
返回值:必须返回一个对象实例
作用:实例化对象
注意:实例化对象是Object底层类实现,其他类继承了Object的__new__才能够实现实例化对象
没事别碰这个魔术方法,先触发__new__才会触发__init__
cat class4.py
#!/usr/bin/env python
# -*-coding:UTF-8 -*-
class Person:
def __init__(self,name):
print('init')
self.name=name
def __new__(cls,*args,**kwargs):
print('new')
p=Person('jack')
print(p)
[root@tecent python]# python class4.py
init
<__main__.Person instance at 0x7f9215e897a0>
[root@tecent python]# python3 class4.py
new
None
cat class4.py
#!/usr/bin/env python
# -*-coding:UTF-8 -*-
class Person:
def __init__(self,name):
print('init')
self.name=name
def __new__(cls,*args,**kwargs):
print('new')
p=Person('jack')
print(p.name)
[root@tecent python]# python class4.py
init
jack
[root@tecent python]# python3 class4.py
new
Traceback (most recent call last):
File "class4.py", line 11, in <module>
print(p.name)
AttributeError: 'NoneType' object has no attribute 'name'
cat class4.py
#!/usr/bin/env python
# -*-coding:UTF-8 -*-
class Person:
def __init__(self,name):
print('init')
self.name=name
def __new__(cls,*args,**kwargs):
print('new')
p=Person('jack')
#print(p.name)
[root@tecent python]# python class4.py
init
[root@tecent python]# python3 class4.py
new
cat class4.py
#!/usr/bin/env python
# -*-coding:UTF-8 -*-
class Person:
def __init__(self):
print('init')
def __new__(cls,*args,**kwargs):
print('new')
return object.__new__(cls,*args,**kwargs)
p=Person()
[root@tecent python]# python class4.py
init
[root@tecent python]# python3 class4.py
注意先调用的__new__
new
init
cat class4.py
#!/usr/bin/env python
# -*-coding:UTF-8 -*-
class Person:
def __init__(self):
print('init')
def __new__(cls,*args,**kwargs): #__new__向内存空间要地址
print('new')
#return object.__new__(cls,*args,**kwargs)
p=Person()
[root@tecent python]# python class4.py
init
[root@tecent python]# python3 class4.py
new
cat class4.py
#!/usr/bin/env python
# -*-coding:UTF-8 -*-
class Person:
def __init__(self):
print('init')
def __new__(cls,*args,**kwargs):
print('new')
return object.__new__(cls)
p=Person()
[root@tecent python]# python3 class4.py
new
init
[root@tecent python]# python class4.py
init
cat class4.py
#!/usr/bin/env python
# -*-coding:UTF-8 -*-
class Person:
def __init__(self,name):
print('init')
self.name=name
def __new__(cls,*args,**kwargs):
print('new')
return object.__new__(cls) #这边出了cls,不用写*args,**kwargs,如果写了__init__会报错
p=Person('jack')
[root@tecent python]# python class4.py
init
[root@tecent python]# python3 class4.py
new
init
call
调用对象的魔术方法
触发时机:将对象当做函数调用时触发对象()
参数:至少一个self接收对象,其余根据调用时参数决定
返回值:根据情况而定
作用:可以将复杂的步骤进行合并操作,减少调用的步骤,方便使用
注意:无
cat class4.py
#!/usr/bin/env python
# -*-coding:UTF-8 -*-
class Person:
def __init__(self,name):
print('init')
self.name=name
def __new__(cls,*args,**kwargs):
print('new')
return object.__new__(cls)
def __call__(self,*args,**kwargs):
print(call)
p=Person('jack')
[root@tecent python]# python3 class4.py
new
init
cat class4.py
#!/usr/bin/env python
# -*-coding:UTF-8 -*-
class Person:
def __init__(self,name):
print('init')
self.name=name
def __new__(cls,*args,**kwargs):
print('new')
return object.__new__(cls)
def __call__(self,*args,**kwargs):
print('call')
p=Person('jack')
p()
[root@tecent python]# python3 class4.py
new
init
call
cat class4.py
#!/usr/bin/env python
# -*-coding:UTF-8 -*-
class Person:
def __init__(self,name):
print('init')
self.name=name
def __new__(cls,*args,**kwargs):
print('new')
return object.__new__(cls)
def __call__(self,name):
print('call')
print(name)
p=Person('jack')
p('hello')
[root@tecent python]# python3 class4.py
new
init
call
hello
cat class5.py
#!/usr/bin/env python
# -*-coding:UTF-8 -*-
class Person:
def __init__(self,name):
self.name=name
p=Person('jack')
p1=p
p2=p
print(p.name)
print(p1.name)
print(p2.name)
[root@tecent python]# python3 class5.py
jack
jack
jack
cat class5.py
#!/usr/bin/env python
# -*-coding:UTF-8 -*-
import sys
class Person:
def __init__(self,name):
self.name=name
p=Person('jack')
p1=p
p2=p
print(p.name)
print(p1.name)
print(p2.name)
print(sys.getrefcount(p))
p1.name='tom'
print(p.name)
print(p1.name)
print(p2.name)
p.name='newton'
print(p.name)
print(p1.name)
print(p2.name)
[root@tecent python]# python3 class5.py
jack
jack
jack
4
tom
tom
tom
newton
newton
newton
del
cat class5.py
#!/usr/bin/env python
# -*-coding:UTF-8 -*-
import sys
class Person:
def __init__(self,name):
self.name=name
def __del__(self):
print('del')
p=Person('jack')
p1=p
p2=p
print(p.name)
print(p1.name)
print(p2.name)
print(sys.getrefcount(p))
p1.name='tom'
print(p.name)
print(p1.name)
print(p2.name)
p.name='newton'
del p2
print(p.name)
print(p1.name)
print(p2.name)
python3 class5.py
jack
jack
jack
4
tom
tom
tom
newton
newton
Traceback (most recent call last):
File "class5.py", line 24, in <module>
print(p2.name)
NameError: name 'p2' is not defined
del
cat class5.py
#!/usr/bin/env python
# -*-coding:UTF-8 -*-
import sys
class Person:
def __init__(self,name):
self.name=name
def __del__(self):
print('del')
p=Person('jack')
p1=p
p2=p
print(p.name)
print(p1.name)
print(p2.name)
print(sys.getrefcount(p))
p1.name='tom'
print(p.name)
print(p1.name)
print(p2.name)
p.name='newton'
del p
print(p.name)
print(p1.name)
print(p2.name)
python3 class5.py
jack
jack
jack
4
tom
tom
tom
Traceback (most recent call last):
File "class5.py", line 22, in <module>
print(p.name)
NameError: name 'p' is not defined
del
cat class5.py
#!/usr/bin/env python
# -*-coding:UTF-8 -*-
import sys
class Person:
def __init__(self,name):
self.name=name
p=Person('jack')
p1=p
p2=p1
print(p.name)
print(p1.name)
print(p2.name)
print(sys.getrefcount(p))
p1.name='tom'
print(p.name)
print(p1.name)
print(p2.name)
p.name='newton'
del p1
print(p.name)
print(p2.name)
print(p1.name)
python3 class5.py
jack
jack
jack
4
tom
tom
tom
newton
newton
Traceback (most recent call last):
File "class5.py", line 22, in <module>
print(p1.name)
NameError: name 'p1' is not defined
cat class5.py
#!/usr/bin/env python
# -*-coding:UTF-8 -*-
import sys
class Person:
def __init__(self,name):
self.name=name
p=Person('jack')
p1=p
p2=p
print(p.name)
print(p1.name)
print(p2.name)
print(sys.getrefcount(p))
p1.name='tom'
print(p.name)
print(p1.name)
print(p2.name)
p.name='newton'
del p
print(p.name)
print(p1.name)
print(p2.name)
python3 class5.py
jack
jack
jack
4
tom
tom
tom
Traceback (most recent call last):
File "class5.py", line 20, in <module>
print(p.name)
NameError: name 'p' is not defined
import sys
del:
1、对象赋值
p=Person()
p1=p
说明:p和p1共同指向同一个地址
2、删除地址的引用
del p1 删除p1对地址的引用
3、查看对地址的引用次数:
import sys
sys.getrefcount§
4、当一块空间没有了任何引用,默认执行__del__(del不建议自己写)
str
说明:单纯打印对象名称,出来的是一个地址,地址对于开发者来说没有太大意义
如果想在打印对象名的时候能够给开发者更多一些信息量,用__str__
触发时机:打印对象名,自动触发去调用__str__里面的内容
注意:一定要在__str__方法中return
cat class6.py
#!/usr/bin/env python
# -*-coding:UTF-8 -*-
#__str__
class Person:
def __init__(self,name):
self.name=name
#def __str__(self):
# return self.name
p=Person('tom')
print(p)
python3 class6.py
<__main__.Person object at 0x7f5c6c9a6f28>
cat class6.py
#!/usr/bin/env python
# -*-coding:UTF-8 -*-
#__str__
class Person:
def __init__(self,name):
self.name=name
def __str__(self):
return self.name
p=Person('tom')
print(p)
python3 class6.py
tom
私有化
属性私有化后之所以访问不到是因为底层将属性改成了_类名__属性名
封装:
1、私有化属性
2、定义公有set和get方法
__属性:就是将属性私有化,访问范围仅仅限于类中
私有化好处
1、隐藏属性不被外界随意修改
2、也可以修改,通过函数
3、筛选赋值内容
if xxx是否符合条件
赋值
else:
不赋值
4、如果想获取具体的某一个属性
使用函数例如
def getXXX(self):
return self.__xxx
cat class7.py
#!/usr/bin/env python
# -*-coding:UTF-8 -*-
class Student:
def __init__(self,name,age):
self.name=name
self.age=age
self.__score=59
def __str__(self):
return '姓名:{},年龄:{},考试分数:{}'.format(self.name,self.age,self.__score)
s=Student('newton','100')
print(s)
python3 class7.py
姓名:newton,年龄:100,考试分数:59
cat class7.py
#!/usr/bin/env python
# -*-coding:UTF-8 -*-
class Student:
def __init__(self,name,age):
self.name=name
self.age=age
self.__score=59
def __str__(self):
return '姓名:{},年龄:{},考试分数:{}'.format(self.name,self.age,self.__score)
s=Student('newton','100')
print(s)
s.name='tom'
s.age=99
s.__score=60
print(s.name)
print(s.age)
print(s.__score)
print(s)
python3 class7.py
姓名:newton,年龄:100,考试分数:59
tom
99
60
姓名:tom,年龄:99,考试分数:59
cat class7.py
#!/usr/bin/env python
# -*-coding:UTF-8 -*-
class Student:
def __init__(self,name,age):
self.__name=name
self.__age=age
self.__score=59
#定义共有set和get
#set是为了赋值
def setAge(self,age):
self.__age=age
pass
def getAge(self,age):
return
def __str__(self):
return '姓名:{},年龄:{},考试分数:{}'.format(self.__name,self.__age,self.__score)
s=Student('newton','100')
print(s)
s.setAge(99)
print(s)
python3 class7.py
姓名:newton,年龄:100,考试分数:59
姓名:newton,年龄:99,考试分数:59
定义公有set和get方法
cat class7.py
#!/usr/bin/env python
# -*-coding:UTF-8 -*-
class Student:
def __init__(self,name,age):
self.__name=name
self.__age=age
self.__score=59
#定义共有set和get
#set是为了赋值
def setAge(self,age):
if age>0 and age<120:
self.__age=age
else:
print('你修仙了吗?')
def getAge(self,age):
return
def __str__(self):
return '姓名:{},年龄:{},考试分数:{}'.format(self.__name,self.__age,self.__score)
s=Student('newton','100')
print(s)
s.setAge(99)
print(s)
s.setAge(150)
print(s)
python3 class7.py
姓名:newton,年龄:100,考试分数:59
姓名:newton,年龄:99,考试分数:59
你修仙了吗?
姓名:newton,年龄:99,考试分数:59
注意,定义共有属性的时候函数名不一定非得是setXXX和getXXX
cat class7.py
#!/usr/bin/env python
# -*-coding:UTF-8 -*-
class Student:
def __init__(self,name,age):
self.__name=name
self.__age=age
self.__score=59
#定义共有set和get
#set是为了赋值
def test1(self,age):
if age>0 and age<120:
self.__age=age
else:
print('你修仙了吗?')
def test2(self,age):
return
def __str__(self):
return '姓名:{},年龄:{},考试分数:{}'.format(self.__name,self.__age,self.__score)
s=Student('newton','100')
print(s)
s.test1(99)
print(s)
s.test1(150)
print(s)
python3 class7.py
姓名:newton,年龄:100,考试分数:59
姓名:newton,年龄:99,考试分数:59
你修仙了吗?
姓名:newton,年龄:99,考试分数:59
访问和改变私有属性(不建议这么做)
cat class7.py
#!/usr/bin/env python
# -*-coding:UTF-8 -*-
class Student:
def __init__(self,name,age):
self.__name=name
self.__age=age
self.__score=59
#定义共有set和get
#set是为了赋值
def test1(self,age):
if age>0 and age<120:
self.__age=age
else:
print('你修仙了吗?')
def test2(self,age):
return
def __str__(self):
return '姓名:{},年龄:{},考试分数:{}'.format(self.__name,self.__age,self.__score)
s=Student('newton','100')
print(s)
s.test1(99)
print(s)
s.test1(150)
print(s)
s._Student__name='tom'
print(s)
#print(s._Student__name)
python class7.py
姓名:newton,年龄:100,考试分数:59
姓名:newton,年龄:99,考试分数:59
你修仙了吗?
姓名:newton,年龄:99,考试分数:59
姓名:tom,年龄:99,考试分数:59
使用装饰器改变私有属性
cat class8.py
#!/usr/bin/env python
# -*-coding:UTF-8 -*-
class Student:
def __init__(self,name,age):
self.name=name
self.__age=age
@property
def age(self):
return self.__age
@age.setter
def age(self,age):
if age>0 and age<120:
self.__age=age
else:
print('你修仙了吗?')
def __str__(self):
return '姓名:{},年龄:{}'.format(self.name,self.__age)
s=Student('newton','100')
s.age=18
print(s.age)
print(s)
python3 class8.py
18
姓名:newton,年龄:18
has-a
练习
两个类
公路(Road):
属性:公路名称,公路长度
车(Car):
方法:1、求车名在那条公路上以多少时速行驶了多长时间,get_time(self,road)
2、初始化属性信息__init__方法
3、打印对象显示车的属性信息
cat instance.py
#!/usr/bin/env python
# -*-coding:UTF-8 -*-
import random
class Road:
def __init__(self,name,len):
self.name=name
self.len=len
class Car:
def __init__(self,brand,speed):
self.brand=brand
self.speed=speed
def get_time(self,road):
ran_time=random.randint(1,10)
msg='{}品牌的车在{}上以{}速度行驶{}小时'.format(self.brand,road.name,self.speed,ran_time)
print(msg)
def __str__(self):
return '{}品牌的,速度:{}'.format(self.brand,self.speed)
#创建实例化
r=Road('京藏高速',12000)
audi=Car('奥迪',120)
print(audi)
audi.get_time(r)
python3 instance.py
奥迪品牌的,速度:120
奥迪品牌的车在京藏高速上以120速度行驶9小时
cat instance.py
#!/usr/bin/env python
# -*-coding:UTF-8 -*-
import random
class Road:
def __init__(self,name,len):
self.name=name
self.len=len
class Car:
def __init__(self,brand,speed):
self.brand=brand
self.speed=speed
def get_time(self,road):
ran_time=random.randint(1,10)
msg='{}品牌的车在{}上以{}速度行驶{}小时'.format(self.brand,road.name,self.speed,ran_time)
print(msg)
def __str__(self):
return '{}品牌的,速度:{}'.format(self.brand,self.speed)
#创建实例化
r=Road('京藏高速',12000)
print(r.name)
r.name='京哈高速'
audi=Car('奥迪',120)
print(audi)
audi.get_time(r)
python3 instance.py
京藏高速
奥迪品牌的,速度:120
奥迪品牌的车在京哈高速上以120速度行驶9小时
cat has-a-instance.py
#!/usr/bin/env python
# -*-coding:UTF-8 -*-
class Computer:
def __init__(self,brand,type,color):
self.brand=brand
self.type=type
self.color=color
def online(self):
print('正在使用电脑上网')
def __str__(self):
return self.brand+self.type+self.color
class Student:
def __init__(self,name,computertest,booktest):
self.name=name
self.computertest=computertest
self.books=[]
self.books.append(booktest)
def borrow_book(self,book):
pass
def __str__(self):
return self.name+self.computertest+self.books #这会报错
class Book:
def __init__(self,bname,author,number):
self.bname=bname
self.author=author
self.number=number
def __str__(self):
return self.bname+self.author+str(self.number)
computer=Computer('mac','mac pro 2018','深灰色')
book=Book('盗墓笔记','南派三叔',10)
student=Student('songsong',computer,book)
print(student)
python has-a-instance.py
注意看报错
Traceback (most recent call last):
File "has-a-instance.py", line 34, in <module>
print(student)
File "has-a-instance.py", line 22, in __str__
return self.name+self.computertest+self.books
TypeError: cannot concatenate 'str' and 'instance' objects
cat has-a-instance.py
#!/usr/bin/env python
# -*-coding:UTF-8 -*-
class Computer:
def __init__(self,brand,type,color):
self.brand=brand
self.type=type
self.color=color
def online(self):
print('正在使用电脑上网')
def __str__(self):
return self.brand+self.type+self.color
class Student:
def __init__(self,name,computertest,booktest):
self.name=name
self.computertest=computertest
self.books=[]
self.books.append(booktest)
def borrow_book(self,book):
pass
def __str__(self):
return self.name+str(self.computertest)+str(self.books)
class Book:
def __init__(self,bname,author,number):
self.bname=bname
self.author=author
self.number=number
def __str__(self):
return self.bname+self.author+str(self.number)
computer=Computer('mac','mac pro 2018','深灰色')
book=Book('盗墓笔记','南派三叔',10)
student=Student('songsong',computer,book)
print(student)
python3 has-a-instance.py
songsongmacmac pro 2018深灰色[<__main__.Book object at 0x7f16261ef668>]
cat has-a-instance.py
#!/usr/bin/env python
# -*-coding:UTF-8 -*-
class Computer:
def __init__(self,brand,type,color):
self.brand=brand
self.type=type
self.color=color
def online(self):
print('正在使用电脑上网')
def __str__(self):
return self.brand+self.type+self.color
class Student:
def __init__(self,name,computertest,booktest):
self.name=name
self.computertest=computertest
self.books=[]
self.books.append(booktest)
def borrow_book(self,booktest):
for book1 in self.books:
if book1.bname==booktest.bname:
print('已经借过此书')
break
else:
#将参数book添加到列表中
self.books.append(booktest)
print('添加成功')
def show_book(self):
for booktest in self.books:
print(booktest.bname)
def __str__(self):
return self.name+str(self.computertest)+str(self.books)
class Book:
def __init__(self,bname,author,number):
self.bname=bname
self.author=author
self.number=number
def __str__(self):
return self.bname+self.author+str(self.number)
computer=Computer('mac','mac pro 2018','深灰色')
book=Book('盗墓笔记','南派三叔',10)
student=Student('songsong',computer,book)
#student.borrow_book(book)
student.show_book()
print(student)
book2=Book('鬼吹灯2','天下霸唱',8)
student.borrow_book(book2)
student.show_book()
```python
python3 has-a-instance.py
盗墓笔记
songsongmacmac pro 2018深灰色[<__main__.Book object at 0x7fba3c374710>]
添加成功
盗墓笔记
鬼吹灯2
类继承
class Parent:
def __init__(self):
self.name='匿名'
self.age=18
def eat(self):
print(self.name + '正在吃饭')
def run(self):
print(self.name + '正在跑步')
class Student(Parent):
pass
class Employee(Parent):
pass
class Doctor(Parent):
pass
s=Student()
s.run()
e=Employee()
d=Doctor()
执行结果
匿名正在跑步
class Parent:
def __init__(self):
self.name='匿名'
self.age=18
def eat(self):
print(self.name + '正在吃饭')
def run(self):
print(self.name + '正在跑步')
class Student(Parent):
def __init__(self):
print('student的类')
#使用super调用父类的方法
super().__init__()
class Employee(Parent):
pass
class Doctor(Parent):
pass
s=Student()
s.run()
e=Employee()
d=Doctor()
执行结果
student的类
匿名正在跑步
class Parent:
def __init__(self,name):
self.name=name
self.age=18
def eat(self):
print(self.name + '正在吃饭')
def run(self):
print(self.name + '正在跑步')
class Student(Parent):
def __init__(self,name):
print('student的类')
#使用super调用父类的方法
super().__init__(name)
class Employee(Parent):
pass
class Doctor(Parent):
pass
s=Student('tom')
s.run()
e=Employee()
d=Doctor()
执行结果
student的类
tom正在跑步
Traceback (most recent call last):
File "C:/Users/Administrator/PycharmProjects/pythonProject1/day16/class1.py", line 24, in <module>
e=Employee()
TypeError: __init__() missing 1 required positional argument: 'name'
class Parent:
def __init__(self,name):
self.name=name
self.age=18
def eat(self):
print(self.name + '正在吃饭')
def run(self):
print(self.name + '正在跑步')
class Student(Parent):
def __init__(self,name):
print('student的类')
#使用super调用父类的方法
super().__init__(name)
class Employee(Parent):
pass
class Doctor(Parent):
pass
s=Student('tom')
s.run()
e=Employee('newton')
d=Doctor('ein')
执行结果
student的类
tom正在跑步
class Parent:
def __init__(self,name):
self.name=name
self.age=18
def eat(self):
print(self.name + '正在吃饭')
def run(self):
print(self.name + '正在跑步')
class Student(Parent):
def __init__(self,name):
print('student的类')
#使用super调用父类的方法
super().__init__(name)
class Employee(Parent):
pass
class Doctor(Parent):
pass
s=Student('tom')
s.run()
e=Employee('newton')
e.run()
d=Doctor('ein')
d.run()
执行结果
student的类
tom正在跑步
newton正在跑步
ein正在跑步
class Parent:
def __init__(self,name,age):
self.name=name
self.age=18
def eat(self):
print(self.name + '正在吃饭')
def run(self):
print(self.name + '正在跑步')
class Student(Parent):
def __init__(self,name,age,clazz):
#使用super调用父类的方法
super().__init__(name,age)
self.clazz=clazz
class Employee(Parent):
def __init__(self,name,age,salary,manager):
super().__init__(name,age)
self.salary=salary
self.manager=manager
class Doctor(Parent):
def __init__(self,name,age,patient):
super(Doctor,self).__init__(name,age) #注意这里super()函数也可以有参数,默认省略
self.patient=patient
s=Student('tom','18','python')
s.run()
e=Employee('newton','19','30000','newton')
e.run()
d=Doctor('ein',19,'ailin')
d.run()
tom正在跑步
newton正在跑步
ein正在跑步
class Parent:
def __init__(self,name,age):
self.name=name
self.age=18
def eat(self):
print(self.name + '正在吃饭')
def run(self):
print(self.name + '正在跑步')
class Student(Parent):
def __init__(self,name,age,clazz):
#使用super调用父类的方法
super().__init__(name,age)
self.clazz=clazz
def study(self,course):
print('{}正在学习{}课程'.format(self.name,course))
def eat(self): #会先调用这里的方法
print(self.name+'正在吃饭...,喜欢吃:狮子头盖饭')
class Employee(Parent):
def __init__(self,name,age,salary,manager):
super().__init__(name,age)
self.salary=salary
self.manager=manager
class Doctor(Parent):
def __init__(self,name,age,patient):
super(Doctor,self).__init__(name,age)
self.patient=patient
s=Student('ein','18','python')
s.run()
s.study('python')
s.eat()
e=Employee('newton','19','30000','newton')
e.run()
d=Doctor('ein',19,'ailin')
d.run()
ein正在跑步
ein正在学习python课程
ein正在吃饭...,喜欢吃:狮子头盖饭
newton正在跑步
ein正在跑步
class Parent:
def __init__(self,name,age):
self.name=name
self.age=18
def eat(self):
print(self.name + '正在吃饭')
def run(self):
print(self.name + '正在跑步')
class Student(Parent):
def __init__(self,name,age,clazz):
#使用super调用父类的方法
super().__init__(name,age)
self.clazz=clazz
def study(self,course):
print('{}正在学习{}课程'.format(self.name,course))
def eat(self,food):
print(self.name+'正在吃饭...,喜欢吃:'+food)
class Employee(Parent):
def __init__(self,name,age,salary,manager):
super().__init__(name,age)
self.salary=salary
self.manager=manager
class Doctor(Parent):
def __init__(self,name,age,patient):
super(Doctor,self).__init__(name,age)
self.patient=patient
s=Student('ein',18,'python')
s.run()
s.study('python')
s.eat('满汉全席')
e=Employee('newton','19','30000','newton')
e.run()
d=Doctor('ein',19,'ailin')
d.run()
ein正在跑步
ein正在学习python课程
ein正在吃饭...,喜欢吃:满汉全席
newton正在跑步
ein正在跑步
总结:
1.如果类中不定义__init__,调用super class的__init__
2.如果类继承父类也需要定义自己的__init__,就需要在当前类的__init__调用一下父类的__init__
3.如何调用父类__init__
super().init(参数)
super(类名,对象).init(参数)
4.如果父类有eat(),子类也定义一个eat方法,默认搜索的原则:先找当前类,再去找父类
s.eat()
overwrite(重写)
父类提供的方法不能满足子类的需求,就需要在子类中定义一个同名的方法,而这种行为就叫做重写。
类继承练习
class Parent:
def __init__(self,no,name,salary):
self.no=no
self.name=name
self.salary=salary
def __str__(self):
msg='工号:{},姓名:{},本月工资:{}'.format(self.no,self.name,self.salary)
return msg
def getSalary(self):
return self.salary
class Worker(Parent):
def __init__(self,no,name,salary,hours,per_hour):
#使用super调用父类的方法
super().__init__(no,name,salary)
self.hours=hours
self.per_hour=per_hour
def getSalary(self):
money=self.hours*self.per_hour
self.salary+=money
return self.salary
class Salesman(Parent):
def __init__(self,no,name,salary,salemoney,percent):
super().__init__(no,name,salary)
self.salemoney=salemoney
self.percent=percent
def getSalary(self):
money=self.salemoney*self.percent
self.salary+=money
return self.salary
w=Worker('001','king',2000,160,50)
s=w.getSalary()
print('月薪是:',s)
print(w)
saler=Salesman('002','lucy',5000,5000000,3)
s=saler.getSalary()
print('月薪是:',s)
print(saler)
月薪是: 10000
工号:001,姓名:king,本月工资:10000
月薪是: 15005000
工号:002,姓名:lucy,本月工资:15005000
类继承中方法覆盖
类中方法同名,最后写的方法覆盖之前的方法
class Parent:
def __init__(self,name):
self.name=name
def eat(self):
print('--------eat1')
def eat(self,food):
print('---------eat2',food)
p=Parent('jack')
p.eat('狮子头')
---------eat2 狮子头
class A:
def test(self):
print('---AAAA')
class B:
def test1(self):
print('---BBBB')
class C(A,B):
def test2(self):
print('---CCCC')
c=C()
c.test()
c.test1()
c.test2()
class Base:
def test(self):
print('---Base')
class A(Base):
def test(self):
print('---AAAA')
class B(Base):
def test(self):
print('---BBBB')
class C(Base):
def test(self):
print('---CCCC')
class D(A,B,C):
pass
d=D()
d.test()
#打印类调用过程
import inspect
print(inspect.getmro(D))
#打印类调用过程
print(D.__mro__)
执行过程
---AAAA
(<class '__main__.D'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.Base'>, <class 'object'>)
(<class '__main__.D'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.Base'>, <class 'object'>)
经典类的搜索顺序
class P1:
def foo(self):
print('p1-foo')
def bar(self):
print('p1-bar')
class P2:
def foo(self):
print('p2-foo')
class C1(P1,P2):
pass
class C2(P1,P2):
def bar(self):
print('C2-bar')
class D(C1,C2):
pass
d=D()
d.foo()
d.bar()
import inspect
print(inspect.getmro(D))
print(D.__mro__)
python2执行结果
p1-foo
p1-bar
(<class __main__.D at 0x7f266978e8d8>, <class __main__.C1 at 0x7f266978e808>, <class __main__.P1 at 0x7f266978e738>, <class __main__.P2 at 0x7f266978e7a0>, <class __main__.C2 at 0x7f266978e870>)
python3执行结果
p1-foo
C2-bar
(<class '__main__.D'>, <class '__main__.C1'>, <class '__main__.C2'>, <class '__main__.P1'>, <class '__main__.P2'>, <class 'object'>)
(<class '__main__.D'>, <class '__main__.C1'>, <class '__main__.C2'>, <class '__main__.P1'>, <class '__main__.P2'>, <class 'object'>)
新式类搜索顺序(python3)
class P1(object):
def foo(self):
print('p1-foo')
def bar(self):
print('p1-bar')
class P2(object):
def foo(self):
print('p2-foo')
class C1(P1,P2):
pass
class C2(P1,P2):
def bar(self):
print('C2-bar')
class D(C1,C2):
pass
d=D()
d.foo()
d.bar()
import inspect
print(inspect.getmro(D))
print(D.__mro__)
python2.7的执行结果为
p1-foo
C2-bar
(<class '__main__.D'>, <class '__main__.C1'>, <class '__main__.C2'>, <class '__main__.P1'>, <class '__main__.P2'>, <type 'object'>)
(<class '__main__.D'>, <class '__main__.C1'>, <class '__main__.C2'>, <class '__main__.P1'>, <class '__main__.P2'>, <type 'object'>)
python3的执行结果为
p1-foo
C2-bar
(<class '__main__.D'>, <class '__main__.C1'>, <class '__main__.C2'>, <class '__main__.P1'>, <class '__main__.P2'>, <class 'object'>)
(<class '__main__.D'>, <class '__main__.C1'>, <class '__main__.C2'>, <class '__main__.P1'>, <class '__main__.P2'>, <class 'object'>)
多态
python其实没有严格的多态
class Person:
def __init__(self,name):
self.name=name
def feed_pet(self,pet):
if isinstance(pet,Pet):
print('{}喜欢养宠物:{},妮称是:{}'.format(self.name,pet.role,pet.nickname))
else:
print('不是宠物类型的')
class Pet:
role='Pet'
def __init__(self,nickname,age):
self.nickname=nickname
self.age=age
def show(self):
print('妮称:{},年龄:{}'.format(self.nickname,self.age))
class Cat(Pet):
role='猫'
def catch_mouse(self):
print('抓老鼠')
class Dog(Pet):
def watch_house(self):
print('看家高手')
class Tiger:
def eat(self):
print('太可怕了,可以吃人')
cat=Cat('花花',2)
dog=Dog('大黄',4)
tiger=Tiger()
person=Person('家伟')
person.feed_pet(cat)
print('======================')
person=Person('pengpeng')
person.feed_pet(tiger)
家伟喜欢养宠物:猫,妮称是:花花
======================
不是宠物类型的