Python类中资源的访问

Python 的类中有三种资源类型, 分别为字段, 方法和属性.

字段又分为静态字段和普通字段

方法分为静态方法, 普通方法和类方法

而字段和方法又能有私有字段和私有方法的形态

本篇文章就来介绍 Python 类中各个资源的访问规则

字段

公有静态字段

  • 在类的外部使用对象名访问
1
2
3
4
5
class A:
name = 'polarsnow'

a = A()
print(a.name)

执行结果为:

1
polarsnow

此种形态是使用实例化后的对象去访问的静态字段, 一般情况下, 最好用对象去访问对象自己的普通字段, 不要用对象来访问静态字段

  • 在类的外部使用类名访问
1
2
3
4
class A:
name = 'polarsnow'

print(A.name)

执行结果为:

1
polarsnow

此种形态是一般情况下, 正确访问类中静态字段的方式, 即使用类名访问

  • 在类的内部使用对象访问
1
2
3
4
5
6
7
8
class A:
name = 'polarsnow'

def f(self):
return self.name

a = A()
print(a.f())

此种情况是在类的内部, 通过一个方法来获取类中静态字段的值, 在方法中, 使用了对象的名字去调用获取了类中静态字段的值, 一般情况下, 上面也说了, 对于类中对静态字段的访问, 需要使用类名去实现, 不推荐使用对象名去调用

  • 在类的内部使用类名访问
1
2
3
4
5
6
7
8
9
10
11
12
13
class A:
name = 'polarsnow'

def f(self):
return A.name

@classmethod
def f2(cls):
return cls.name

a = A()
print(a.f())
print(a.f2())

执行结果为:

1
2
polarsnow
polarsnow

此种情况下, 我通过两种方式, 用类名获取了静态字段的值. 如果使用普通方法的话, 默认方法内的形参只传递了对象的名字, 如果想显示地调用类中的静态字段的话, 需要明确地指定类名; 但是如果是用对象方法的话, 对象方法默认帮我们传递了对象的名字, 所以我们可以使用cls变量直接调用静态字段

私有静态字段

  • 在类的内部使用类方法访问
1
2
3
4
5
6
7
8
9
10
11
12
13
class A:
__name = 'polarsnow'

def f(self):
return A.__name

@classmethod
def f2(cls):
return cls.__name

a = A()
print(a.f())
print(a.f2())

执行结果为:

1
2
polarsnow
polarsnow

私有的静态字段, 不能在外部使用对象或类名调用, 只能通过在类的内部访问. 上面的例子提供了两种方式来访问私有的静态字段. 一种是在普通方法内通过显示指定来访问, 一种是在类方法中, 通过形参, 隐式地通过cls类名来访问

方法

公有方法

  • 静态方法
  • 普通方法
  • 类方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class A:
name = 'polarsnow'

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

def f(self):
return self.name

@classmethod
def f2(cls):
return cls.name

@staticmethod
def f3():
return '123'

a = A('lvrui')
print(a.f())
print(a.f2())
print(a.f3())

执行结果为:

1
2
3
lvrui
polarsnow
123

在普通方法中, python 隐式传递了对象名; 在类方法总, python 隐式传递了类名; 而静态方法的本质既没有用到对象也没有用到类, 如果静态方法拿到外面来, 就是 python 中普通的函数而已, 之所以把这种函数也放到类中, 是为了方便类中相关操作的聚合, 同一类的操作放到同一个类下

私有方法

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
29
30
31
32
class A:
name = 'polarsnow'

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

def __f(self):
return self.name

def ff(self):
return self.__f()

@classmethod
def __f2(cls):
return cls.name

@classmethod
def ff2(cls):
return cls.__f2()

@staticmethod
def __f3():
return '123'

@staticmethod
def ff3():
return A.__f3()

a = A('lvrui')
print(a.ff())
print(a.ff2())
print(a.ff3())

执行结果为:

1
2
3
lvrui
polarsnow
123

每种类型的方法访问均可以访问自己的私有方法. 在共有静态方法调用私有静态方法时需要注意, 只能使用类名去访问私有静态方法

在实际使用中, 对于私有方法的访问, 也可以跨类型访问, 比如我可以用一个普通方法去调用一个私有的类方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class A:
name = 'polarsnow'

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

def f(self):
return self.__f2()

@classmethod
def __f2(cls):
return cls.name


a = A('lvrui')
print(a.f())

执行结果为:

1
polarsnow

属性

私有属性

1
2
3
4
5
6
7
8
9
10
11
12
13
class A:

@property
def __name(self):
return 'polarsnow'

@property
def n(self):
return self.__name


a = A()
print(a.n)

执行结果为:

1
polarsnow