面向对象的成员与嵌套

成员:

一.变量

  变量包括:实例变量(字段)和类变量(静态字段),在定义和使用中有区别,本质区别是内存中保存的位置不同.(实例变量保存在对象中,类变量保存在类中.)

class Provice:
    country = '中国'          #类变量
    def __init__(self, name):
        self.name = name      #实例变量
# 访问实例变量,通过对象
obj = Provice('北京市')
print(obj.name)
#访问类变量,通过类
print(Provice.country)
结果:
北京市
中国

  实例变量与类变量的内存位置:

   类变量在内存中只保存一份

   实例变量在每个对象中都保存一份

 应用场景: 通过类创建对象时,如果每个对象都具有相同的字段,那么就使用静态字段.

二.方法

  方法包括:普通方法,静态方法,类方法.三种方法在内存中都在类中,区别在于定义和调用方式不同.

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

  静态方法: 由类调用,定义时在方法上面写@staticmethod,无默认参数.

  类方法: 由类调用,定义时在方法上面写@classmethod,至少有一个cls参数,执行类方法时,自动调用该方法的类复制给cls.

class Foo:
    def func(self):         #至少有一个self参数
        print('普通方法')
    @classmethod
    def func1(cls):         #至少有一个cls参数
        print('类方法')
    @staticmethod
    def func2():            #可以没有参数
        print('静态方法')
obj = Foo()                 #实例化一个对象
obj.func()                  #通过对象调用普通方法
obj.func1()                 #可以通过对象调用类方法,一般不建议用
obj.func2()                 #可以通过对象调用静态方法,一般不建议用

Foo.func1()                 #通过类调用类方法
Foo.func2()                 #通过类调用静态方法
结果:
普通方法
类方法
静态方法

类方法
静态方法

  相同点: 所有的方法,都属于类中,在内存中只保存一份.

  不同点: 方法的定义不同,调用时自动传入的参数不同.

  静态方法的使用: 如果方法无需使用对象中封装的值,就可以使用静态方法.

三.属性

  属性是普通方法的变种

class Foo:
def func(self):
print('普通方法')
@property #定义属性时,方法上面加@property
def func1(self): #属性定义时,只有一个self参数,不能加参数
return '属性'

obj = Foo()
obj.func() #普通方法调用时,需要加括号
ret = obj.func1 #属性调用时,无需加括号
print(ret)
结果: 
普通方法
属性

  属性存在的意义是调用的时候不需要加括号.

  属性的应用场景: 类中的方法,既不需要传参数且有返回结果.可以使用@property.

类的成员修饰符

  每一个类的成员都有两种形式: 公有成员, 私有成员

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

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

  公有成员与私有成员的定义不同:私有成员命名时,前两个字符是下划线.(__init__等特殊成员除外)

class Foo:
    def __init__(self):
        self.name = '公有字段'
        self.__foo = '私有字段'
    def per(self):
        print(self.__foo)
obj = Foo()
print(obj.name)
obj.per()
print(obj.__foo)
结果:
公有字段
私有字段
报错

  公有成员与私有成员的访问限制不同:

  字段:

    公有字段:对象可以访问,类内部可以访问,派生类也可以访问.

    私有字段:只有类内部可以访问.

class Foo:
    def __init__(self):
        self.foo = '公有字段'
    def func(self):
        print(self.foo)         #类内部访问
class Foo1(Foo):
    def show(self):
        print(self.foo)         #派生类访问
obj = Foo()
print(obj.foo)                  #通过对象访问
obj.func()                      #类内部访问

obj1 = Foo1()
obj1.show()                     #派生类访问
结果:
公有字段
公有字段
公有字段
公有字段
class Foo:
    def __init__(self):
        self.__foo = '私有字段'
    def func(self):
        print(self.__foo)           #类内部访问
class Foo1(Foo):
    def show(self):
        print(self.__foo)           #派生类访问
    def per(self):
        self.func()
obj = Foo()
obj.func()                          #类内部访问==>正确
# print(obj.__foo)                    #通过对象访问==>错误

obj1 = Foo1()
# obj1.show()                         #派生类访问==>错误
obj1.per()                               #派生类通过基类内部访问==>正确.
                                              #实质是通过类内部访问       
私有字段

  静态字段:

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

    私有静态字段:只有类内部可以访问.

class Foo:
    name = '公有静态字段'
    def func(self):
        print(Foo.name)
class Foo1(Foo):
    def show(self):
        print(Foo.name)

print(Foo.name)             #类访问

obj = Foo()
obj.func()                  #类内部可以访问

obj1 = Foo1()
obj1.show()                 #派生类中可以访问
结果:
公有静态字段
公有静态字段
公有静态字段
公有静态字段
class Foo:
    __name = '私有静态字段'
    def func(self):
        print(Foo.__name)
class Foo1(Foo):
    def show(self):
        print(Foo.__name)
    def per(self):
        self.func()
print(Foo.__name)          #类访问==>错误

obj = Foo()
obj.func()                 #类内部访问==>正确

obj1 = Foo1()
obj1.show()                #派生类中访问==>错误

obj1.func()                #派生类通过基类内部访问==>正确
私有静态字段

  方法,属性的成员修饰符与上述方式相似.私有成员只能在类内部使用.

  注意:如果非要访问私有属性,可以通过对象._类__属性名

class Foo:
    __name = '私有静态字段'
    def func(self):
        print(Foo.__name)
class Foo1(Foo):
    def show(self):
        print(Foo.__name)
    def per(self):
        self.func()

obj = Foo()
print(obj._Foo__name)
结果:
私有静态字段
通过对象._类__属性名访问私有属性
原文地址:https://www.cnblogs.com/Virous1887/p/9548856.html