专栏首页python3Python基础之(八)类

Python基础之(八)类

创建类

  • 第一形式
# !/usr/bin/env python
# coding=utf-8

class Person(object): #object表示继承自object类,Python3中可省略次内容
    """
    This is a sample of Class
    """
    breast = 90  #类的属性 是静态变量
    
    def __init__(self, name): #初始化方法  self为对象实例本身
        self.name = name
        
    def get_name(self):  #类的方法
        return self.name
    
    def color(self,color):
        d = {}
        d[self.name] = color;
        return d
    
if __name__ == "__main__":
    girl = Person("songjia")
    print girl.name
    girl.name ="liu"
    print girl.get_name()
    print girl.color("white")
    girl.breast = 80 #修改实例的属性
    print girl.breast
    print Person.breast #类属性不会随实例属性的改变而改变
    Person.breast = 100
    print Person.breast
    print girl.breast
  • 第二种形式
>>> __metaclass__ = type
>>> class CC:
...     pass
... 
>>> cc = CC()
>>> cc.__class__
<class '__main__.CC'>
>>> type(cc)
<class '__main__.CC'>

实例

girl = Person("songjia")

类属性

>>> class A(object):    #Python 3: class A:
...         x = 7  #类的属性
... 

下面列出类的几种特殊属性的含义:

  • C.__name__:以字符串的形式,返回类的名字,注意这时候得到的仅仅是一个字符串,它不是一个类对象
  • C.__doc__:显示类的文档
  • C.__base__:类C的所有父类。如果是按照上面方式定义的类,应该显示object,因为以上所有类都继承了它。等到学习了“继承”,再来看这个属性,内容就丰富了
  • C.__dict__:以字典形式显示类的所有属性
  • C.__module__:类所在的模块

实例属性

>>> class A(object):    #Python 3: class A:
...         x = 7  #类的属性
... 
>>> foo = A()
>>> foo.x #实例属性

类中变量引用可变数据

>>> class B(object):
...     y = [1, 2, 3]
    
   >>> B.y         #类属性
[1, 2, 3]
>>> bar = B()
>>> bar.y       #实例属性
[1, 2, 3]

>>> bar.y.append(4)
>>> bar.y
[1, 2, 3, 4]
>>> B.y
[1, 2, 3, 4]

>>> B.y.append("aa")
>>> B.y
[1, 2, 3, 4, 'aa']
>>> bar.y
[1, 2, 3, 4, 'aa']

当类中变量引用的是可变对象是,类属性和实例属性都能直接修改这个对象,从而影响另一方的值。

访问限制

# !/usr/bin/env python
# coding=utf-8

class Person(object):
    """
    This is a sample of Class
    """
    
    def __init__(self, name): #初始化方法  self为对象实例本身
        self.__name = name #__xx双下划线表示类的私有变量
        
    def get_name(self):  #类的方法
        return self.__name #类的内部可以访问
    
if __name__ == "__main__":
    girl = Person("songjia")
    print girl.get_name()
    print girl._name #无法访问类的私有变量

文档字符串

在函数、类或者文件开头的部分写文档字符串说明,一般采用三重引号。这样写的最大好处是能够用help()函数看。

"""This is python lesson"""

def start_func(arg):
   """This is a function."""
   pass

class MyClass:
   """This is my class."""
   def my_method(self,arg):
       """This is my method."""
       pass

继承

单继承

#!/usr/bin/env python
# coding=utf-8

class Person(object):        #Python 3: class Person:
    def __init__(self, name):
        self.name = name
    
    def height(self, m):
        h = dict((["height", m],))
        return h

    def breast(self, n):
        b = dict((["breast", n],))
        return b

class Girl(Person):  #继承
    def get_name(self):
        return self.name

if __name__ == "__main__":
    cang = Girl("liuguoquan")
    print cang.get_name()        #Python 3: print(cang.get_name()),下同,从略
    print cang.height(160)
    print cang.breast(90)

调用覆盖的方法

class Girl(Person):
   def __init__(self, name):
       #Person.__init__(self, name) #调用父类的方法
       super(Girl, self).__init__(name) #调用父类的方法常用写法
       self.real_name = "Aoi sola"

   def get_name(self):
       return self.name
       
if __name__ == "__main__":
   cang = Girl("canglaoshi")
   print cang.real_name
   print cang.get_name()
   print cang.height(160)
   print cang.breast(90)

执行结果为:

    Aoi sola
    canglaoshi
    {'height': 160}
    {'breast': 90}

多继承

#!/usr/bin/env python
# coding=utf-8

class Person(object):        #Python 3: class Person:
    def eye(self):
        print "two eyes"

    def breast(self, n):
        print "The breast is: ",n

class Girl(object):        #Python 3: class Gril:
    age = 28
    def color(self):
        print "The girl is white"

class HotGirl(Person, Girl): #多重继承
    pass

if __name__ == "__main__":
    kong = HotGirl()
    kong.eye()
    kong.breast(90)
    kong.color()
    print kong.age
    
two eyes
The breast is:  90
The girl is white
28

多重继承的顺序-广度优先

class K1(object):        #Python 3: class K1:
   def foo(self):
       print "K1-foo"    #Python 3: print("K1-foo"),下同,从略

class K2(object):        #Python 3: class K2:
   def foo(self):
       print "K2-foo"
   def bar(self):
       print "K2-bar"

class J1(K1, K2):
   pass

class J2(K1, K2):
   def bar(self):
       print "J2-bar"

class C(J1, J2):
pass
   
if __name__ == "__main__":
print C.__mro__
m = C()
m.foo()
m.bar()
   
K1-foo
J2-bar

代码中的print C.__mro__是要打印出类的继承顺序。从上面清晰看出来了。如果要执行foo()方法,首先看J1,没有,看J2,还没有,看J1里面的K1,有了,即C==>J1==>J2==>K1;bar()也是按照这个顺序,在J2中就找到了一个。

这种对继承属性和方法搜索的顺序称之为“广度优先”。 Python 2的新式类,以及Python 3中都是按照此顺序原则搜寻属性和方法的。

方法

绑定方法

#!/usr/bin/env python
# coding=utf-8

class Person(object):        #Python 3: class Person:
    def eye(self):
        print "two eyes"

    def breast(self, n):
        print "The breast is: ",n

class Girl(object):        #Python 3: class Gril:
    age = 28
    def color(self):
        print "The girl is white"

class HotGirl(Person, Girl): #多重继承
    pass

if __name__ == "__main__":
    kong = HotGirl() #实例化实现了方法和实例的绑
    kong.eye() #调用绑定方法

非绑定方法

在子类中,父类的方法就是非绑定方法,因为在子类中,没有建立父类的实例,却要是用父类的方法。

静态方法和类方法

#!/usr/bin/env python
# coding=utf-8

__metaclass__ = type

class StaticMethod: #静态方法
    @staticmethod
    def foo():
        print "This is static method foo()."

class ClassMethod: #类方法
    @classmethod
    def bar(cls): #类方法必须有cls参数
        print "This is class method bar()."
        print "bar() is part of class:", cls.__name__

if __name__ == "__main__":
    static_foo = StaticMethod()    #实例化
    static_foo.foo()               #实例调用静态方法
    StaticMethod.foo()             #通过类来调用静态方法
    print "********"
    class_bar = ClassMethod()
    class_bar.bar()
    ClassMethod.bar()
    
This is static method foo().
This is static method foo().
********
This is class method bar().
bar() is part of class: ClassMethod
This is class method bar().
bar() is part of class: ClassMethod

在python中:

  • @staticmethod表示下面的方法是静态方法
  • @classmethod表示下面的方法是类方法

多态和封装

多态

class Cat:
   def speak(self):
       print "meow!"

class Dog:
   def speak(self):
       print "woof!"

class Bob:
   def bow(self):
       print "thank you, thank you!"
   def speak(self):
       print "hello, welcome to the neighborhood!"
   def drive(self):
       print "beep, beep!"

def command(pet):
   pet.speak()

pets = [ Cat(), Dog(), Bob() ]

for pet in pets:
   command(pet)

Python中的多态特点,Python不检查传入对象的类型,这种方式被称之为“隐式类型”(laten typing)或者“结构式类型”(structural typing),也被通俗的称为“鸭子类型”(duck typeing),Python是弱类型语言。

Java会检查传入对象的类型,所以是强类型语言。

封装和私有化

要了解封装,离不开“私有化”,就是将类或者函数中的某些属性限制在某个区域之内,外部无法调用。

Python中私有化的方法也比较简单,就是在准备私有化的属性(包括方法、数据)名字前面加双下划线。例如:

#!/usr/bin/env python
# coding=utf-8

class ProtectMe(object):        #Python 3: class ProtectMe:
    def __init__(self):
        self.me = "qiwsir"
        self.__name = "kivi" #私有变量

    def __python(self): #私有方法
        print "I love Python."        

    def code(self):
        print "Which language do you like?"
        self.__python()

if __name__ == "__main__":
    p = ProtectMe()
    print p.me
    print p.code()

如何将一个方法变成属性调用?

可以使用property函数。

#!/usr/bin/env python
# coding=utf-8

class ProtectMe(object):        #Python 3: class ProtectMe:
    def __init__(self):
        self.me = "qiwsir"
        self.__name = "kivi" #私有变量

    def __python(self): #私有方法
        print "I love Python."        

    @property
    def code(self):
        print "Which language do you like?"
        self.__python

if __name__ == "__main__":
    p = ProtectMe()
    print p.me
    print p.code #调用方法名即可

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Python中接口定义和依赖注入

    首先,我们必须明确的一点是:python里无接口类型,定义接口只是一个人为规定,在编程过程自我约束

    py3study
  • Python基础练习100题 ( 41

    这十道题的代码在我的github上,如果大家想看一下每道题的输出结果,可以点击以下链接下载:

    py3study
  • python 成员

    py3study
  • python面向对象反射-框架原理-动态导入-元类-自定义类-单例模式-项目的生命周期-05

    ​ 反射其实就是对属性的增删改查,但是如果直接使用内置的__dict__来写,语法繁琐,不好理解;另一个主要问题是,如果对象不是自己写的,而是另一方提供的,我就...

    suwanbin
  • Python中接口定义和依赖注入

    首先,我们必须明确的一点是:python里无接口类型,定义接口只是一个人为规定,在编程过程自我约束

    py3study
  • Python之面向对象二

    面向对象的三大特性: 继承 继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类 pyt...

    新人小试
  • 10 . Python之面向对象

    类中的方法一般都是通过对象执行的(除去类方法,静态方法外),并且对象执行这些方法都会自动将对象空间传给方法中的第一个参数self

    常见_youmen
  • 8.python面向对象编程

    基本概念 Class 类 一个类即是对一类拥有相同属性的对象的抽象、蓝图、原型。在类中定义了这些对象的都具备的属性(variables(data))、共同的方法...

    zhang_derek
  • Python多态

    多态:同类对象的多种形态,一个接口多种实现,(以封装和继承为前提),不同的子类调用相同的方法,产生不同的结果

    橙子探索测试
  • python 高级编程:类方法、实例方法、静态方法的定义个区别

    AI之禅

扫码关注云+社区

领取腾讯云代金券