[TOC]

文章参考:https://www.jianshu.com/p/44f2740c0db9

概述

Python面向对象编程中,类中定义的方法可以是 @classmethod 装饰的类方法,也可以是 @staticmethod 装饰的静态方法,用的最多的还是不带装饰器的实例方法,如果把这几个方法放一块,对初学者来说无疑是一头雾水,那我们该如何正确地使用它们呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Person(object):
def name1(self, name):
print("self:", self)

@classmethod
def name2(cls, name):
print("cls:", cls)

@staticmethod
def name3(name):
pass

person = Person()
person.name1(1) # self: <__main__.A object at 0x000001E596E41A90>
Person.m2(1) # cls: <class '__main__.A'>
Person.m3(1)

我在类中一共定义了3个方法,name1 是实例方法,第一个参数必须是 self(约定俗成的)。name2 是类方法,第一个参数必须是cls(同样是约定俗成),name3 是静态方法

我们来依次讲解一下这三种方法:

实例方法

类方法

很容易理解,先来说一下类方法的作用:让这个函数只能访问类变量,而不能访问实例变量。

静态方法

属性方法

python的@property是python的一种装饰器,是用来修饰方法的。

我们可以使用@property装饰器来创建只读属性,@property装饰器会将方法转换为相同名称的只读属性,可以与所定义的属性配合使用,这样可以防止属性被修改。

使用场景:

1.修饰方法,是方法可以像属性一样访问。

1
2
3
4
5
6
7
8
9
10
class DataSet(object):
@property
def method_with_property(self): ##含有@property
return 15
def method_without_property(self): ##不含@property
return 15

l = DataSet()
print(l.method_with_property) # 加了@property后,可以用调用属性的形式来调用方法,后面不需要加()。
print(l.method_without_property()) #没有加@property , 必须使用正常的调用方法的形式,即在后面加()

两个都输出为15。

1
2
3
4
5
6
class DataSet(object):
@property
def method_with_property(self): ##含有@property
return 15
l = DataSet()
print(l.method_with_property()) # 加了@property后,可以用调用属性的形式来调用方法,后面不需要加()。

如果使用property进行修饰后,又在调用的时候,方法后面添加了(), 那么就会显示错误信息:TypeError: ‘int’ object is not callable,也就是说添加@property 后,这个方法就变成了一个属性,如果后面加入了(),那么就是当作函数来调用,而它却不是callable(可调用)的。

2.与所定义的属性配合使用,这样可以防止属性被修改。

由于python进行属性的定义时,没办法设置私有属性,因此要通过@property的方法来进行设置。这样可以隐藏属性名,让用户进行使用的时候无法随意修改。

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
class ModifiedMethodClass:

def __init__(self):
self.id = 1
self.name = "方法修饰符" # 定义属性的名称

@property
def func_property(self):
return 10

@property
def get_id(self):
"""
方法加入@property后,这个方法相当于一个属性,这个属性可以让用户进行使用,而且用户有没办法随意修改。
:return:
"""
return self.id


classInstance = ModifiedMethodClass()

# 不能在后面加() 否则 TypeError: 'int' object is not callable
print(classInstance.func_property)

# 用户进行属性调用的时候,直接调用images即可,而不用知道属性名_images,因此用户无法更改属性,从而保护了类的属性。
print(classInstance.get_id) # 加了@property后,可以用调用属性的形式来调用方法,后面不需要加()。