Python是一门面向对象的语言。面向对象的设计思想是抽象出类(Class),根据类(Class)创建实例对象(Instance)。 如果你没有具有相关的知识,请自行查找。本教程都是面向具有基本面向对象知识的人群。

一切皆为对象

python中一切皆为对象。一切都可赋值给变量或作为参数传递给函数。

例如,函数赋值给变量

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
def hi(name="yasoob"):
    return "hi " + name

print(hi())
# output: 'hi yasoob'

greet = hi
print(greet())
# output: 'hi yasoob'

del hi
print(hi())
#outputs: NameError
print(greet())
#outputs: 'hi yasoob'

函数作为参数传递给函数,也就是前面所讲的高阶函数。

类(Class)和实例(Instance)

类是用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。根据类创建的对象是实例。

定义类

定义类有两种形式

形式1

1
2
class Class_Name(object):
    pass

形式2

1
2
class Class_Name:
    pass

class后面紧接着是类名,类名通常是大写开头,紧接着是(object),表示该类是从哪个类继承,(object)可以省略,默认是从object继承。

类实例

创建实例是通过类名+()实现。

1
2
3
4
5
class Person(object):
    pass

#创建实例hank
hank = Person()

属性引用

和Python中所有的属性引用一样,用句点引用属性。对象.属性名

1
2
3
4
5
6
7
8
9
class Person(object):
    i = 12345

    def hello(self):
        return "hello"

hank = Person()
print("hank的属性i的值:",hank.i)
print("hank的方法hello的输出:",hank.hello())

执行以上程序会输出如下结果:

1
2
hank的属性i的值: 12345
hank的方法hello的输出: hello

以上创建了一个新的类实例并将该对象赋给局部变量hank。

特殊方法init

python中以双下划线开头和双下划线结尾的方法都是特殊方法,是为了实现特定功能为准备的。init方法是实例的初始化方法,类实例一旦创建,就会自动调用init方法,进行初始化。

init方法的第一个参数永远是self,表示创建的实例本身。有了init方法,创建实例必须传入与init方法匹配的参数,但self不需要。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
class Person(object):
    #定义__init__方法
    def __init__(self, name, age):
        self.name = name
        self.age = age

    #定义say_name方法,返回实例的属性name的值
    def say_name(self):
        return self.name

#创建实例hank
hank = Person('Hank', 59)

#调用实例的属性和方法
print("hank的属性name的值:",hank.name)
print("hank的属性age的值:",hank.age)
print("hank的方法say_name的输出:",hank.say_name())

执行以上程序会输出如下结果:

1
2
3
hank的属性name的值: Hank
hank的属性age的值: 59
hank的方法say_name的输出: Hank

按照惯例,类中实例的方法第一个参数是self,但这不是必须的,也可以是其他。下面用me取代self,实现相同的效果。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
class Person(object):
    #定义__init__方法,第一个参数是me。
    def __init__(me, name, age):
        me.name = name
        me.age = age

    #定义say_name方法,返回实例的属性name的值。第一个参数是me。
    def say_name(me):
        return me.name

#创建实例hank
hank = Person('Hank', 59)

#调用实例的属性和方法
print("hank的属性name的值:",hank.name)
print("hank的属性age的值:",hank.age)
print("hank的方法say_name的输出:",hank.say_name())

执行以上程序会输出如下结果:

1
2
3
hank的属性name的值: Hank
hank的属性age的值: 59
hank的方法say_name的输出: Hank

实例属性和类属性

实例的属性,简称实例属性。通过self变量(也就是类中的实例方法)或者实例变量来给实例绑定属性。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
class Student(object):
    #通过self变量(也就是类中的实例方法)绑定了实例属性name
    def __init__(self, name):
        self.name = name

s = Student('Bob')
#通过实例变量s,绑定实例属性score
s.score = 90

#输出实例的属性
print("实例s的属性name的值:",s.name)
print("实例s的属性score的值:",s.score)

执行以上程序会输出如下结果:

1
2
实例s的属性name的值: Bob
实例s的属性score的值: 90

类属性

类的属性,简称类属性。雷属性通过在class中定义(不是实例方法),这种属性是类属性,归类所有。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Student(object):
    #定义类属性name
    name = 'Student'

    def __init__(self, age):
        self.age = age

# 创建实例s
s = Student(20)

# 打印Student类的属性name的值
print("Student类的属性name的值:",Student.name)

# 打印name属性,因为实例并没有name属性,所以会继续查找class的name属性
print("s实例的属性name的值:",s.name)

# 给实例绑定name属性
s.name = 'Michael'
# 由于实例属性优先级比类属性高,因此,它会屏蔽掉类的name属性
print("绑定后s实例的属性name的值:",s.name)

# 但是类属性并未消失,用Student.name仍然可以访问
print("绑定后Student类的属性name的值:",Student.name)

# 如果删除实例的name属性
del s.name
# 再次调用s.name,由于实例的name属性没有找到,类的name属性就显示出来了
print("删除s实例的属性name后的值:",s.name)

执行以上程序会输出如下结果:

1
2
3
4
5
Student类的属性name的值: Student
s实例的属性name的值: Student
绑定后s实例的属性name的值: Michael
绑定后Student类的属性name的值: Student
删除s实例的属性name后的值: Student

有些教程中也称类属性是类静态变量,实例属性是类动态变量。

实例方法和类方法

实例方法是类中自定义的方法,第一个参数是self。实例方法,只有实例才能调用。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
class Person(object):
    #实例方法__init__,python解释器自动执行此方法
    def __init__(self, name, age):
        self.name = name
        self.age = age

    #实例方法say_name
    def say_name(self):
        return self.name

#创建实例hank
hank = Person('Hank', 59)

#调用实例的属性和方法
print("hank的属性name的值:",hank.name)
print("hank的属性age的值:",hank.age)
print("hank的方法say_name的输出:",hank.say_name())

运行结果是:

1
2
3
hank的属性name的值: Hank
hank的属性age的值: 59
hank的方法say_name的输出: Hank

类调用实例方法,会报错。提示没有self参数。如下。

1
2
3
4
5
Person.say_name()
Traceback (most recent call last):
  File "main.py", line 18, in <module>
    Person.say_name()
TypeError: say_name() missing 1 required positional argument: 'self'

类方法是类中自定义的方法,没有参数self。类方法,只有类本身才能调用。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
class Person(object):
    #实例方法__init__,python解释器自动执行此方法
    def __init__(self, name, age):
        self.name = name
        self.age = age

    #类方法say_name,没有self参数
    def say_name():
        return "Person"
#创建实例hank
hank = Person('Hank', 59)

#调用类方法
print("Person的方法say_name的输出:",Person.say_name())

运行结果是:

1
Person的方法say_name的输出: Person

实例调用类方法,会报错。提示没有self参数。如下。

1
2
3
4
5
hank.say_name()
Traceback (most recent call last):
  File "main.py", line 14, in <module>
    hank.say_name()
TypeError: say_name() takes 0 positional arguments but 1 was given

类静态方法

类静态方法是用@staticmethod修饰的,没有self参数的方法。静态方法属于类,类和对象都可以进行调用。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
class Person(object):
    #实例方法__init__,python解释器自动执行此方法
    def __init__(self, name, age):
        self.name = name
        self.age = age

    #类静态方法say_name,没有self参数
    @staticmethod
    def say_name():
        return "Person"
#创建实例hank
hank = Person('Hank', 59)

#调用类静态方法
print("实例hank调用类静态方法的输出:",hank.say_name())
print("类Person调用类静态方法的输出:",Person.say_name())

运行结果是:

1
2
实例hank调用类静态方法的输出: Person
Person调用类静态方法的输出: Person

为了同类静态方法相呼应,有些教程里面,实例方法也被称为类动态方法。

实例方法的属性调用方式

在实例方法前面加入@property装饰器,这个方法就变成了类的属性,可以以调用属性的方式进行方法的调用。定义只读属性,只定义getter方法,不定义setter方法。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
class Person(object):
    #实例方法__init__,python解释器自动执行此方法
    def __init__(self, name, age):
        self.name = name
        self.age = age

    #类静态方法say_name,没有self参数。只读属性。
    @property
    def say_name(self):
        return "Person"
#创建实例hank
hank = Person('Hank', 59)

#以调用属性的方式调用实例方法
print("实例hank实例方法:",hank.say_name)

运行结果是:

1
实例hank实例方法: Person

转载请注明本网址。