Python类

一、理解

类相当于模板,对象是类的实例。

可以把类理解成做饼干的模子,对象就是用模子做出的饼干。

我们定义一个class的时候,我们实际上就定义了一种数据类型,我们定义的数据类型和python自带的数据类型,比如str,list,dict没什么两样

二、定义

class ClassName:

  'xxxxx'    # 类文档字符串,可通过ClassName.__doc__查看

  class_suite    # 类体

三、类的实例

定义完成后,并不会真正创建一个实例。这就好比一个汽车的设计图。设计图可以告诉你汽车看上去怎么样,但设计图本身不是一个汽车。你不能开走它,它只能用来建造真正的汽车,而且可以使用它制造很多汽车。那么如何创建实例呢?

ClassName(parameterlist)   

# ClassName:是必选参数,用于指定类。
# parameterlist:可以选参数,当创建一个类时,没有创建__init__()方法,或者当__init__()方法只有一个self参数时, parameterlist可以省略。

例如:
# 创建类
class Geese:
    """大雁类"""
    pass


# 创建实例
wildGoose = Geese()

判断一个变量是否是某个类型可以用isinstance()判断: isinstance(wildGoose,Geese),返回true

四、魔术(构造)方法

在创建类后,类通常会自动创建一个__init__()方法。该方法是一个特殊的方法,类似JAVA 语言中的构造方法。每当创建一个类的新实例时,Python都会自动执行它。init()方法必须包含一个参数,并且必须是第一参数。self参数是一个指向实例本身的引用,用于访问类中的属性和方法。
在方法调用时会自动传递实际参数self。因此,当__init__()方法只有一个参数时,在创建类的实例时,就不需要指定参数了。

# 创建类
class Geese:
    """大雁类"""

    def __init__(self):
        print("我是大雁类")

wildGoose = Geese()

在__init__()方法中,除了self参数外,还可以自定义一些参数,参数间使用逗号“,”进行分隔。例如,下面的代码将在创建__init__()方法时,再指定3个参数,分别是beak、wing和claw:

# 创建类
class Geese:
    """大雁类"""

    def __init__(self, beak, wing, claw):
        print("我是大雁类!我有一下特征:")
        print(beak)
        print(wing)
        print(claw)

beak_1 = ""
wing_1 = "翅膀"
claw_1 = ""
wildGoose = Geese(beak_1, wing_1, claw_1)

五、类的成员

类的成员主要由实例方法和数据成员组成。

5.1 实例方法

所谓实例方法是指在类中定义函数。该函数是一种在类的实例上操作的函数。同__init__()方法一样,实例方法的第一参数必须是self,并且必须包含一个self参数。

def functionName(self,parameterlist):
    block

访问实例方法,通过类的实例名称和点(.)操作符进行访问

instanceName.functionName(parametervalue)

5.2数据成员

5.2.1 类属性

类属性是指在定义类中,并且在函数体外的属性。类属性可以在类的所有实例之间共享值,也就是在所有实例化的对象中公用。

1.在实例化对象中是公用的。

2.定义在类中且在函数体之外。

3.通常不作为实例变量使用。

4.ClassName.bianliang来访问

lass Geese:
    """大雁类"""
    beak_1 = "喙,比较尖"  # 定义类属性(喙)
    wing_1 = "翅膀,比较大" 
    claw_1 = "爪,行走自如"

    def __init__(self):
        print("我是大雁类!我有一下特征:")
        print(Geese.beak_1)   # 输出喙的属性
        print(Geese.wing_1)
        print(Geese.claw_1)

5.2.3 实例属性

实例属性是指定义在类的方法中的属性,只作用于当前实例中。

1.定义在方法中的变量。

2.只作用于当前实例的类。

3.实例名.bianliang来访问

# 创建类
class Geese:
    """大雁类"""
    def __init__(self):
        self.beak_1 = "喙,比较尖"  # 定义实例属性(喙)
        self.wing_1 = "翅膀,比较大"
        self.claw_1 = "爪,行走自如"
        print("我是大雁类!我有一下特征:")
        print(self.beak_1)   # 输出喙的属性
        print(self.wing_1)
        print(self.claw_1)

六、访问属性

getattr(obj, name[, default]) : 访问对象的属性。

hasattr(obj,name) : 检查是否存在一个属性。

setattr(obj,name,value) : 设置一个属性。如果属性不存在,会创建一个新属性。

delattr(obj, name) : 删除属性。

内置类属性:

__dict__ :类的属性

__doc__ :类的文档字符串

__name__:类名

__module__:类定义所在的模块(类的全名是'__main__.className',如果类位于一个导入模块mymod中,那么className.__module__ 等于 mymod)

__bases__:类的所有父类构成元素(包含了一个由所有父类组成的元组)

七、访问限制

但Python并没有对属性和方法的访问权限进行限制。为了保证类内部的某些属性或方法不被外部所访问,可以在属性或方法名前面添加单下划线(_foo)、双下划线(__foo)或者首尾加双下划线( __ foo __),从而限制访问权限。

__ foo __ :首尾双下划线表示定义特殊方法,也称作魔术方法,一般是系统定于名字,如__init__()

_foo:以单下划线开头的表示protected(保护)类型的成员,只允许类本身或子类访问,但不能使用“ from module impor”语句导入

__foo:双下划线表示private(私有)类型的成员,只允许定义该方法的类本身进行访问即只能在类内部方法中通过self.__foo使用,而且也不能通过类的实例进行访问,但是可以通过“类的实例名.类名 __xxx”方式访问。私有只是一种约定, 隐藏实现的细节,只对外公开我们想让他们使用的属性和方法,这就叫做封装

八、继承

所有类都会继承Object类,父类的构造(__init__())方法不会被自动调用,issubclass(sub,sup) 尔函数判断一个类是另一个类的子类或者子孙类,isinstance(obj, Class) 布尔函数如果obj是Class类的实例对象或者是一个Class子类的实例对象则返回true

class ClassName(baseclasslist): #baseclasslist用于指定要继承的基类,可以有多个,类名之间用逗号“,”隔开。如不指定,将使用所有Python对象的根类object
    """类的帮助信息"""     # 类的文档字符串
    statement             # 类体

基类的成员都会被派生类继承,当基类中的某个方法不完全适用于派生类时,就需要在派生类中重写父类的这个方法

class Fruit:  # 定义水果基类
    color = "绿色"  # 定义类属性

    def harvest(self, color):
        print("水果是:" + color + "")  # 输出形式参数
        print("水果已经收获......")
        print("水果原来是:" + Fruit.color + "")  # 输出类属性color


class Orange(Fruit):  # 定义橘子类(派生类)
    color = "橙色"

    def __init__(self):
        print("\n我是橘子")

    def harvest(self, color):
        print("橘子是:" + color + "")  # 输出形式参数
        print("橘子已经收获......")
        print("橘子原来是:" + Fruit.color + "")  # 输出类属性color

在派生类中定义__init__()方法时,不会自动调用基类的__init__()方法。因此在派生类中使用基类的__init__()方法,必须要进行初始化,即需要在派生类中使用super()函数调用基类的__init__()方法。

class Fruit:  # 定义水果基类
    def __init__(self, color="绿色"):
        Fruit.color = color  # 定义类属性

    def harvest(self):
        print("水果原来是:" + Fruit.color + "")  # 输出类属性color


class Apple(Fruit):  # 定义苹果类(派生类)
    def __init__(self):
        print("我是苹果")
        super().__init__()  # 调用基类的__init__()方法


apple = Apple()  # 创建类的实例(苹果)
apple.harvest()  # 调用基类的harvest()方法

九、多态

必要条件 要有继承+重写   即使多态

十、封装

python的面向对象, 并没有严格意义上的私有属性和方法, 私有只是一种约定, 隐藏实现的细节,只对外公开我们想让他们使用的属性和方法,这就叫做封装,封装的目的在于保护类内部数据结构的完整性, 因为使用类的用户无法直接看到类中的数据结构,只能使用类允许公开的数据,很好地避免了外部对内部数据的影响,提高了程序的可维护性。用户只能通过暴露出来的方法访问数据时,你可以在这些方法中加入一些控制逻辑,以实现一些特殊的控制

十一、析构函数

用于初始化类的内容部状态,Python提供的构造函数式 __init__(),也就是当该类被实例化的时候就会执行该函数,__init__()方法是可选的,如果不提供,Python 会给出默认的__init__方法。

“__del__”是析构函数,当使用del 删除对象时,会调用他本身的析构函数,另外当对象在某个作用域中调用完毕,在跳出其作用域的同时析构函数也会被调用一次,这样可以用来释放内存空间。  

__del__()也是可选的,如果不提供,则Python 会在后台提供默认析构函数

如果要显式的调用析构函数,可以使用del关键字: del obj

 

posted @ 2017-08-28 09:59  eudaemonia  阅读(187)  评论(0编辑  收藏  举报