python04 面向对象编程02

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python04 面向对象编程02相关的知识,希望对你有一定的参考价值。

为啥要用类而不用函数呢
  1. 记住两个原则:
  •     减少重复代码
  •     代码会经常变更

    2    会对变量或字符串的合法性检测(在实例初始化的时候能够统一初始化各个实例的变量,换做函数来说,要弄出同样的变量那么在初始化的时候必须一个一个的去写代码,容易写错。)
    3   类能够隐藏属性或者变量。
 
 
 
 
 
python 类的三大特性:
  • 1 封装:就是把客观事物封装成抽象的类,而且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏

  • 2 继承:它可以使用现有类的所有功能,并且在无须重新编写原来的类的情况下对这些功能进行扩展,继承是从一般到特殊的过程,父类是定义一般的方法,而子类是有特殊的方法,所以这就是从一般到继承的过程。

  • 3 多态:实现的目的在于对接口的重用

 

-------------------------------------------------------------------------------------
拿代码去说话:
  python多态:
#!/usr/bin/env python

#定义一个父类
class animal(object):
  #定义一个类变量
  hobbie=eat meat
  def __init__(self,name):
    self.name=name
  def talk(self):
    print(talking.......)

#定义一个子类
class dog(animal):
  def talk(self):
  print(‘i am dog ,wangwangwang‘)
  return i am dog ,wangwangwang

#定义一个子类,继承父类 class cat(animal):   def talk(self):   #print(‘miao miao miao‘)   return miao miao miao   #定义一个函数,用来调用实例的方法,这样对外的话,我提供了一个接口来分别给使用者调用talk方法   def animal_talk(obj):   print(obj.talk()) d=dog(ljf) #定义实例的变量,变量名是hobbie,这个实例的hobbie不同于类的hobbie,所以在print的时候只会打印实例的hobbie, d.hobbie=fish print(d.hobbie) c=cat(yq) #这个实例c由于没有自己的类变量hobbie,所以在打印的时候就显示类的变量hobbie print(c.hobbie) animal_talk(d) animal_talk(c)

 

------------------------------------------------------------------------------------------
 
 
类的方法(私有变量和装饰器)
-------------------------------------------------------------------------------------------
 
 
 
#!/usr/bin/env python

class animal(object):
  name
=1990
  def __init__(self,name):   self.name=name   #加了两个下划线后的变量名,此时变为了私有属性,也就是私有变量   self.__num=private   def talk(self):
    print("%s are talking"%self.name)   #类方法,不能够访问实例变量,把walk方法变成了类方法,可以直接类名.方法名调用,但是要注意的是walk里 # 面的代码块的变量或者其他的对象都应该是类可以访问的。   @classmethod   def walk(self):     #由于添加了类方法的装饰器,所以这里的%s只能用类属性(animal.name,也叫类变量)去赋值给%s,     print("\\t\\t%s are talking"%self.name)   #静态方法,不再传self参数进去。所以不能够访问类变量以及实例变量,如果添加了self,那么就要在调用的时候把实例名传进去   @staticmethod   def habit():     print("%s‘s habbit : walking"%animal.name)   @property #把方法变成属性,那么调用的时候可以不用加括号(),一般是为了隐藏该方法   def runing(self):     print("%s is running"%self.name)   def r_private(self):     return self.__num   @property   def total_players(self):     return self.__num   #这样可以修改添加了@property里面的值   @total_players.setter   def total_players(self,num):     self.num=num     print("total players:",self.num) animal.walk() d=animal(ljf) d.walk() d.habit() d.runing #咱们访问私有变量一般都是写个方法,通过方法返回私有变量 d.r_private() #下面的直接加两个下划线来访问私有属性是错误的方法 #print(d.__num) #通过下面的赋值的方法,等于新建了一个__num的变量。这个和私有变量__num是两码事 d.__num=ahahh print(d.__num) #强制访问私有变量,实例名._类名__私有变量名 print(d._animal__num)

 

1 问如何去访问私有属性
我们一般是在类里面设定一个方法,例子:
class a(object):
      ......省略一万字
      def access_private(self):
             return self.__private
 
b=a()
b.access_private()
 如果要用比较暴力的方法去访问的话,那么就只能像下面这样操作
  b._a__private
-------------------------------------------------------------------------------------------
 
面向对象特性之多态:
#!/usr/bin/env python
class foo(object):
"""
    this class was test
    """
  name=ljf
  age=123
  def __init__(self):
    self.tt=durex
  def f1(self):
    print(ssssss)
  def __call__(self, *args, **kwargs):
    print("use call method")

a
=foo() #__doc__ 打印类的注释信息 print(a.__doc__) #__dict__ 打印类里面的类变量,下面a.__dict__是打印实例的变量 print(a.__dict__) #类或对象中的所有成员(所有变量) print(foo.__dict__) #__call__ 这个的话是在类实例化后的对象加个括号出发,如x=class(),x()这样在实例化之后就加个()能够触发 a() #__init__() 是构造方法,在实例化的时候就会触发执行 #__module__ 和__class__ #__module__表示当前操作的对象在哪个模块里面 #__class__表示当前操作的对象的类是什么

 

‘‘‘
__del__ 析构方法,当对象在内存中被释放时,自动触发执行。注:此方法一般无须定义,因为Python是一门高级语言,
程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,
析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。
‘‘‘
 
新式类搜索的优先级
在python2.7  2.6版本内是这样的:
1 经典类是深度优先
2 新式类是广度优先
在python3.0 版本是:
不关新式类还是经典类,都是广度优先。

 

#!/usr/bin/env python
‘‘‘
类的继承之深度优先还是广度优先
‘‘‘

class A:
  def f1(self):
    print("f1 from A")
  def f2(self):
    print("f2 from A")
class B:
  def f1(self):
    print("f1 from B")
  def f2(self):
    print("f2 from B")

class C:
  def f1(self):
    print("f1 from C")
  def f2(self):
  print("f2 from C")

class D(B,C):   pass d=D()
‘‘‘
此时D继承了类B,C,那么执行f1方法的时候,首先从同样等级的父类的子类里面,从左往右执行。也就是首先从B里面找f1,f2,
如果B里面没有f1,f2,那么就找C里面的,C里面也没有的话就往C和B的父类往上找,直到找到为止,这就是广度优先
在python2.7 2.6版本内是这样的:
1 经典类是深度优先
2 新式类是广度优先
在python3.0 版本是:
不关新式类还是经典类,都是广度优先。
‘‘‘
d.f1()
d.f2()
 

抽象类:

我们在父类中定义了一个方法
比如
class father(object):
   .....
    def ChouXiang(self):
            pass
 
子类继承了父类,必须写这个ChouXiang方法,不然它就没法工作,所以子类继承父类后必须重写某个类,那么这个类就叫做抽象类
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

以上是关于python04 面向对象编程02的主要内容,如果未能解决你的问题,请参考以下文章

VSCode自定义代码片段9——JS中的面向对象编程

Python中的面向对象编程(类编程)由简单到复杂的示例代码

Python面向对象编程-02

Python深入04 闭包

Python深入04 闭包

Python面向对象编程02:深度认识类class