python对象

类和对象

类属性和对象属性

当实例化对象的时候,加了新的属性并赋值,会优先使用对象属性(即使类中也有同样的属性),当对象属性没做改变时,使用类属性。

类中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)
家伟喜欢养宠物:猫,妮称是:花花
======================
不是宠物类型的
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

时空无限

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值