初识类(一)

本章核心笔记:命名类、属性和方法的标准

类名通常是由大写字母开头,这是标准惯例。

数据的属性听起来应当是数据值的名字。

方法应当是对象或者值的行为。

另外一种是:数据值是名词作为名字,方法是动词加对象。

 

本章主要知识点:

类和实例

方法

创建类

创建实例

访问实例属性

方法调用

创建子类

使用子类

 

 

在python2.2版本中,统一了类型(type)和类(class)。什么意思了?

sb = SongBird()
print(type(sb))
print(type([]))
结果:
<class '__main__.SongBird'>  #都是类
<class 'list'>

list本来是一种数据类型,现在都统一成了类。

python中的一切都是类的实例。

1.类和实例

类与实例的关联:类是实例的定义,而实例是真正的实物,它存放了类中定义的对象的具体信息。

class MyNewObjectType(bases):
    'define MyNewObjectType class'
    pass

定义一个类,关键字是class,紧接着是一个类名。随后是定义的类体代码。

新式类和经典类声明的最大不同在于,所有新式类必须继承至少一个父类。参数bases可以是一个(单继承)或多个(多重继承)用于继承的父类。

object是所有类之母,如果你的类没有继承其他任何父类,object将作为默认的父类。它位于所有类继承结构的最上层

如果你没有直接或间接的子类化一个对象,那么你就定义了一个经典类。

如果你没有指定一个父类,或者如果所子类化的基本类没有父类,这样就是创建了一个经典类。

很多经典类虽然已经过时,但是你仍然会使用它们。

 

创建一个实例的过程叫实例化,就像下面这样

myFirstObject = MyNewObjectType()

通常对于新建的类我们会给他赋值,因为如果你没有把这个实例保存在变量中,它就没用了,会被自动垃圾回收器回收,因为没有任何引用指向这个实例。

类可以很简单,也可以很复杂。最简单的情况,类仅用作名称空间。

这意味着你把数据保存在变量中,对它们按名称空间进行分组,使得它们处于同样的关系空间中,这种类仅仅作为空间容器

 

2.方法

我们改进类的方式之一就是给类添加功能,类的功能有一个更通俗的名字叫做方法。

在python中,方法在类中定义,但只能在类中调用。比如说,list就是一种类,而每创建的一个list表就是它的实例,表的方法在类中定义,比如append,只能在表中调用。

调用一个方法的过程必须只这样的:

(1)定义类(和方法)

(2)创建一个实例

(3)实例调用方法

就像这样:

#定义一个类
class Bird:
    def __init__(self):
        self.hungry = True
    def ear(self):   #定义一个方法
        if self.hungry :
            print('Aaaah...')
            self.hungry = False
        else:
            print('No,thanks')

#创建一个实例
b = Bird()

#调用方法
b.ear()

你可能注意到了self参数,但不知道是啥,说实话我也不懂啊。

它会在所有方法的声明中都存在。self这个参数代表实例对象本身,当你实例调用方法时,由解释器悄悄的传递给方法,所以你不需要自己传递self进来,因为它是自动传入的。

举例说明一下,假如你有一个带两个参数的方法,你只需要传递第二个参数,python会把self作为第一个参数传进来。(实例在调用方法的时候,会把类传递进来,因为类中有方法的定义啊,不然如何调用。)

后面,我们还会介绍一个特殊的方法__init__(),子类化及继承。在实例化的过程中会调用__init__()方法,进行初始化。

 

3.创建一个类(类定义)

class AddrBookEntry(object):
    "address book entry class"
    def __init__(self,nm,ph):  #定义构造器
        self.name = nm         #设置name参数
        self.phone = ph        #设置phone参数,没有默认参数必须要传参。
        print("Created instance for:",self.name)
    def updatePhone(self,newph):  #方法二
        self.phone = newph
        print("Updated phone# for:",self.name)

在AddrBookEntry类的定义中,定义了两个方法:__init__()和updatePhone()。

__init__()在实例化时(也就是创建一个实例)被调用,即,在AddrBookEntry()被调用时,你可以认为实例化是对__init__()的一种隐式调用。

因为传给AddrBookEntry()的参数与__init__()接受到的参数是一样的,除了self,它是自动传递。

回忆一下,当方法在实例中被调用的时候,self是个标志,由解释器自动传入,所以在上面的__init__()中,需要的参数是nm和ph,它们分别表示名字和电话号码。

__init__()在实例化过程中,会设置这两个属性,以便在实例从实例化调用中返回时,这两个属性对程序员时间可见的。

 

4.创建实例(实例化)

john = AddrBookEntry('John Doe','408-555-1212')
jane = AddrBookEntry('Jane Doe','650-555-1212')

这就是实例化的调用,它会自动调用__init__()。self把实例对象自动传入__init__()。然在实例中就可以设置属性了。

在实例化后,其中的参数就被替换掉了。

如果不存在默认参数,那么传给__init__()的两个参数在实例化时是必须的。

 

5.访问实例属性

print(john)
print(john.name)
print(john.phone)
print(jane.name)
print(jane.phone)

结果:
<__main__.AddrBookEntry object at 0x0000017FD4CCD978>
John Doe
408-555-1212
Jane Doe
650-555-1212

一旦实例被创建,就可以查证在实例化过程中,我们的实例属性是否确实被__init__()设置了

__init__()初始化实际上是属性赋值的过程。

 

6.方法的调用

john.updatePhone('415-555-1212')
print(john.phone)

结果:
415-555-1212

updatePhone()方法至少需要一个参数,当然self不在之内,新的电话号码被更新之后,检查属性,已经失效。

 

7.创建子类

靠继承来进行子类化是创建和定制新类型的一种方式,新的类将保持已存在类所有的特性,而不会改动原来类的定义。

对于新类类型而言,这个新的子类可以制定只属于它的特定功能,除了与父类或基类的关系之外,子类与通常的类没有什么区别,也可以像一般类一样进行实例化。

class EmplAddrBookEntry(AddrBookEntry):
    'Employee Address Book Entry class' #员工地址簿
    def __init__(self,nm,ph,id,em):
        AddrBookEntry.__init__(self,nm,ph)#借用超类的初始化特性,也就是参数的属性,不然你无法调用,因为没有搭建调用的环境。
        self.empid = id
        self.email = em
    def updateEmail(self,newem):
        self.email = newem
        print("Update e-maile address for:",self.name)

上面我们创建了一个子类EmplAddrBookEntry().

在python中,当一个类被派生出来,子类就继承了基类(也叫父类)的属性,上面新定义了__init__()和updateEmail()方法,也继承了updatePhone()方法。

如果需要,每个子类最好定义它自己的构造器,不然,基类的构造器就会被调用,然而,如果子类重新定义了基类的构造器,基类的构造器就不会被调用了。

 

8.使用子类

print(john)
>><__main__.EmplAddrBookEntry object at 
0x00000236839BDA58>

print(john.phone)   #继承了基类的属性
>>408-555-1212

print(john.name)
>>John Doe

print(john.email)
>>john@spam.doc  #自己特有的属性

john.updatePhone('415-555-1212')
>>Updated phone# for: John Doe  #继承基类的方法

print(john.phone)
>>415-555-1212

print(john.email)
>>john@spam.doc

 

posted @ 2017-12-20 15:33  明王不动心  阅读(238)  评论(0编辑  收藏  举报