Python 的类中有三种资源类型, 分别为字段, 方法和属性.
字段又分为静态字段和普通字段
方法分为静态方法, 普通方法和类方法
而字段和方法又能有私有字段和私有方法的形态
本篇文章就来介绍 Python 类中各个资源的访问规则
字段
公有静态字段
1 2 3 4 5
| class A: name = 'polarsnow'
a = A() print(a.name)
|
执行结果为:
此种形态是使用实例化后的对象去访问的静态字段, 一般情况下, 最好用对象去访问对象自己的普通字段, 不要用对象来访问静态字段
1 2 3 4
| class A: name = 'polarsnow'
print(A.name)
|
执行结果为:
此种形态是一般情况下, 正确访问类中静态字段的方式, 即使用类名访问
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())
|
执行结果为:
此种情况下, 我通过两种方式, 用类名获取了静态字段的值. 如果使用普通方法的话, 默认方法内的形参只传递了对象的名字, 如果想显示地调用类中的静态字段的话, 需要明确地指定类名; 但是如果是用对象方法的话, 对象方法默认帮我们传递了对象的名字, 所以我们可以使用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())
|
执行结果为:
私有的静态字段, 不能在外部使用对象或类名调用, 只能通过在类的内部访问. 上面的例子提供了两种方式来访问私有的静态字段. 一种是在普通方法内通过显示指定来访问, 一种是在类方法中, 通过形参, 隐式地通过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())
|
执行结果为:
在普通方法中, 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 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 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)
|
执行结果为: