上一篇学习了Python面向对象的3大特性,封装,继承和多态,这一篇继续学习类成员,包括字段,方法,属性以及他们的修饰符。


1.字段

字段分为静态字段和普通字段。静态字段属于类,而普通字段属于对象,因此静态字段在内存中只保存一份,而普通字段在每个对象中都保存了一份。定义的时候静态字段定义在类的范围里面,而普通字段定义在方法里面。


例如:

>>> class Foo:
    # 字段(静态字段)
    CC = 123
    def __init__(self):
        # 字段(普通的字段)
        self.name = 'alex'
    def show(self):
        print(self.name)
obj=Foo()
print(obj.name)
print(Foo.CC)
print(obj.CC)
---------------------
alex
123
123


注意上面,尽管我们通过对象也能调用静态字段,这种方式应该尽量避免!



2.方法

方法包括静态方法,普通方法和类方法。

静态方法:由类调用,无默认参数;

普通方法:由对象调用,至少一个self参数,执行的时候,自动把对象赋值给self

类方法:由类调用,至少一个cls参数,执行的时候,自动将该方法的类赋值给cls


例如:

class Province:
    #静态字段
    country = "中国"
    def __init__(self,name):
        self.name = name
    # 普通方法,由对象去调用执行(方法属于类)
    def show(self):
        # print(self.name)
        print(123)
        
    @staticmethod
    def f1(cla,a1,a2):
        # 静态方法,由类调用执行。(当方法内部不需要对象中封装的值时,可以将方法写成静态方法)
        print(a1,a2)
        
    @classmethod
    def f2(cls):# class
        cls # 类名,()创建对象
        # cls()
        print(cls)
        
    def f3(self):
        return self.name[1]
        
obj = Province("河南")
obj.show()
Province.f1(Province,1,2)
Province.f2()
obj = Province('alex')
ret = obj.f3()
print(ret)
-------------
123
1 2

l



3.属性

属性的本质就是一个方法,不过我们通过调用字段的方式去调用他。字段可以调用a=obj.name,可以赋值obj.name='alex',可以删除del obj.name,属性自然也需要实现这些功能


属性有2种方式来定义:装饰器方式或者静态字段的方式


首先看看装饰器方式,分别在普通方法上面添加@property, @xx.settler @xx.deleter就能实现了,当我们调用,赋值,和删除的时候他会自动调用对应的方法

例如

class Foo:

    def func(self):
        pass

    # 定义属性
    @property
    def prop(self):
        print('property')

    @prop.setter
    def prop(self,value):
        print("settle")

    @prop.deleter
    def prop(self):
        print("deletter")
# ############### 调用 ###############
foo_obj = Foo()

foo_obj.func()
foo_obj.prop
foo_obj.prop=200
del foo_obj.prop
---------------------
property
settle
deletter



第二种方式是通过静态字段的方式

class Pager:

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

    def f1(self):
        return 123

    def f2(self,value):
        print('setup')

    def f3(self):
        print('del')

    foo = property(fget=f1,fset=f2, fdel=f3)

p = Pager(101)

result = p.foo
print(result)
p.foo = "alex"
del p.foo
-------------
123
setup
del


  • 第一个参数是方法名,调用 对象.属性 时自动触发执行方法

  • 第二个参数是方法名,调用 对象.属性 = XXX 时自动触发执行方法

  • 第三个参数是方法名,调用 del 对象.属性 时自动触发执行方法

  • 第四个参数是字符串,调用 对象.属性.__doc__ ,此参数是该属性的描述信息



4.修饰符

所有的类成员都有两种形式

公有成员:任何地方都能访问

私有成员:只有类的内部可以访问

命名形式很简单,就是前两个字符是下划线__(注意和特殊成员区分开)


静态字段

  • 公有静态字段:类可以访问;类内部可以访问;派生类中可以访问

  • 私有静态字段:仅类内部可以访问;


class C:
    name = "公有静态字段"
    def func(self):
        print (C.name)
class D(C):
    def show(self):
        print (C.name)
print(C.name)         # 类访问
obj = C()
obj.func()     # 类内部可以访问
obj_son = D()
obj_son.show() # 派生类中可以访问
----------------
公有静态字段
公有静态字段
公有静态字段


如果改成私有静态字段,那么类不可以访问,派生类也不可以访问

class C:
    __name = "私有静态字段"
    def func(self):
        print (C.__name)
class D(C):
    def show(self):
        print (C.__name)
# print(C.__name)         # 类无法访问
obj = C()
obj.func()     # 类内部可以访问
obj_son = D()
# obj_son.show() # 派生类中不可以访问
------------------
私有静态字段


普通字段

  • 公有普通字段:对象可以访问;类内部可以访问;派生类中可以访问

  • 私有普通字段:仅类内部可以访问;


class C:
    def __init__(self):
        self.__foo = "私有普通字段"
    def func(self):
        print(self.__foo)
class D(C):
    def show(self):
        print(self.__foo)
obj = C()
# obj.__foo  # 通过对象访问    ==> 错误
obj.func()  # 类内部访问        ==> 正确
obj_son = D();
# obj_son.show()  # 派生类中访问  ==> 错误
------------------
私有字段



方法和属性的访问方式和上面相似。