面向对象是一种编程方式,此编程方式的实现是基于对类和对象的使用。类是一个模板,模板中包含了多个'函数'供使用,对象是根据模板创建的实例,实例用于调用被包装在类中的函数。
类成员
类的成员可以分为三类:字段、方法和属性
所有成员中,只有普通字段的内容保存在对象中,即:根据此类创建了多少对象,在内存中就有多少个普通字段。而其他的成员,则都是保存在类中,即:无论对象多少,在内存中只创建一份
字段
字段包括普通字段和静态字段。普通字段属于对象,静态字段属于类。它们在定义和使用中有所却别,而本质的区别是内存中保存的位置不同。静态字段在内存中只保存一份,普通字段在每个对象中都要保存一份
class Province(): country = 'China' #静态字段 def __init__(self,name): self.name = name #普通字段 obj = Province('四川省') print(obj.name) #访问普通字段 print(Province.country) #访问静态字段
方法
方法包括:普通方法,静态方法和类方法。三种方法在内存中都归属于类,区别在于调用方式不同
class Animal(): name = 'animal' def __init__(self,name): self.name = name def ord_func(self): #普通方法,即绑定到对象的方法 print('普通方法由对象调用,自动将对象赋值给self,对象的名字为%s'%self.name) @classmethod def class_method(cls): #类方法,即绑定到类的方法 print('类方法由类调用,自动将该方法的类赋值给cls,类的名字为%s'%cls.name) @staticmethod def static_method(): #静态方法,即非绑定方法,不会自动传值 print('静态方法无默认参数') cat = Animal('cat') cat.ord_func() #对象也可以调用类方法,自动将该对象所属的类赋值给cls cat.class_method() cat.static_method() #对象和类都可以调用静态方法
属性
在普通方法的基础上添加@property装饰器,访问该属性就和访问该字段相同了。属性即将内部进行一系列逻辑运算,最终将计算结构返回,调用该属性即可获得最终的返回值。
class myBMI(): def __init__(self,height,weight): self.height = height self.weight = weight @property def MBI(self): return self.height/self.weight**2 tom = myBMI(175,75) print(tom.MBI)
属性的两种定义方式
#装饰器方式 class Goods: def __init__(self): self.original_price = 100 self.discount = 0.8 @property def price(self): new_price = self.original_price * self.discount return new_price @price.setter def price(self, value): self.original_price = value @price.deleter def price(self): del self.original_price obj = Goods() obj.price # 获取商品价格 obj.price = 200 # 修改商品原价 print(obj.price) del obj.price # 删除商品原价
class Animal(): def __init__(self,name): self.name = name def get_name(self): return self.name NAME = property(get_name) cat = Animal('cat') print(cat.NAME)
# property的构造方法中有个四个参数 # 第一个参数是方法名,调用 对象.属性 时自动触发执行方法 # 第二个参数是方法名,调用 对象.属性 = XXX 时自动触发执行方法 # 第三个参数是方法名,调用 del对象.属性 时自动触发执行方法 # 第四个参数是字符串,调用 对象.属性.__doc__ ,此参数是该属性的描述信息 class Goods(object): def __init__(self): self.original_price = 100 self.discount = 0.8 def get_price(self): new_price = self.original_price * self.discount return new_price def set_price(self, value): self.original_price = value def del_price(self): del self.original_price PRICE = property(get_price, set_price, del_price, '价格属性描述...') obj = Goods() obj.PRICE # 自动调用第一个参数中定义的方法:get_price obj.PRICE = 200 # 自动调用第二个参数中定义的方法:set_price方法,并将“200”当作参数传入 obj.PRICE.__doc__ # 自动获取第四个参数中设置的值:价格属性描述。。。 del obj.PRICE # 自动调用第三个参数中定义的方法:del_price方法
类成员的修饰符
对于每一个类的成员都有两种形式:公有成员和私有成员。公有成员在任何地方都能访问,私有成员只有在类的内部才能访问
定义
#定义不同 class Foo(): def __init__(self): self.name = '公有字段' self.__foo = '私有字段' #私有成员命名时前两个字符是下划线,特殊成员除外:__init__,__call__等
访问
静态字段
#公有静态字段:类可以访问;类内部可以访问;派生类中可以访问 #私有静态字段:仅类内部可以访问 class C: name = "公有静态字段" def func(self): print (C.name) class D(C): def show(self): print (C.name) 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) C.__name # 类访问 ==> 错误 obj = C() obj.func() # 类内部可以访问 ==> 正确 obj_son = D() obj_son.show() # 派生类中可以访问 ==> 错误
普通字段
#公有普通字段:对象可以访问;类内部可以访问;派生类中可以访问 #私有普通字段:仅类内部可以访问 #如果想要强制访问私有字段,可以通过 【对象._类名__私有字段明 】访问(如:obj._C__foo),不建议强制访问私有成员 #公有字段 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() # 派生类中访问 #私有字段 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() # 派生类中访问 ==> 错误
属性的访问与字段相似,即:私有成员只能在类内部使用。非要访问私有属性的话,可以通过对象.__类__属性名