成员
一类的成员
1.变量(字段)
字段包括:实例变量(普通字段)和类变量(静态字段),他们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同.
准则:
实例变量(字段)访问时,使用对象访问,即: obj1.name
类变量(静态字段)访问时,使用类方法,即: Foo.country (实在不方便时,才使用对象)
知识点一: 什么时候用类变量?
当所有对象中有共同的字段时且要改都改要删都删时,可以实例变量(字段) 提取到 类变量(静态字段)
class Province: # 静态字段(类变量) country = "中国" def __init__(self,name): # 普通字段(实例变量) self.name = name #直接访问普通字段 obj = Province("北京省") print(obj.name) #直接访问静态字段 Province.country #结果:北京省
实例变量(普通字段)属于对象
公有实例变量(字段)
私有实例变量(字段)
静态字段属于类
公有类变量(静态字段)
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() #派生类中可以访问 ==>错误 #结果:公有静态字段
静态字段在内存中只保存一份
普通字段在每个对象中都要保存一份
应用场景: 通过类创建对象时,如果每个对象都具有相同的字段,那么就使用静态字段
#无法访问 class Base(object):
#私有实例变量(私有字段) __secret = "受贿" class Foo(Base): def func(self): print(self.__secret) print(Foo.__secret) obj = Foo() obj.func() # 无法访问 #结果:报错 #可以访问 class Base(object): __secret = "受贿" def zt(self): print(Base.__secret) class Foo(Base): def func(self): print(self.__secret) print(Foo.__secret) obj = Foo() obj.zt() #结果:受贿
2.方法
方法包括:实例方法(普通方法)、静态方法和类方法,三种方法在内存中都归属于类,区别在于调用方式不同。
普通方法:由对象调用;至少一个self参数;执行普通方法时,自动将调用该方法的对象赋值给self;
class Foo(object): def __init__(self,name): self.name = name #实例方法 def func(self): print(self.name) obj = Foo("wang") obj.func() #结果:wang
静态方法:由类调用;无默认参数;
class Foo(object): def __init__(self,name): self.name = name #静态方法,如果方法无需使用对象中封装的值,那么就可以使用静态方法 @staticmethod def display(a1,a2): return a1 + a2 set = Foo.display(1,3) print(set) #结果:4
总结
1. 编写时:
- 方法上方写 @staticmethod
- 方法参数可有可无
2. 调用时:
- 类.方法名() *
- 对象.方法名()
3. 什么时写静态方法?
- 无需调用对象中已封装的值.
类方法:由类调用; 至少一个cls参数;执行类方法时,自动将调用该方法的类复制给cls;
class Foo(object): #类方法,cls是类 @classmethod def show(cls,x1,x2): print(cls,x1,x2) Foo.show(1,8) #结果:<class '__main__.Foo'> 1 8
总结
1. 定义时:
- 方法上方写: @classmethod
- 方法的参数: 至少有一个cls参数
2. 执行时:
- 类名.方法名() # 默认会将当前类传到参数中.
3. 什么时用?
- 如果在方法中会使用到当前类,那么就可以使用类方法.
相同点:对于所有的方法而言,均属于类(非对象)中,所以,在内存中也只保存一份。
不同点:方法调用者不同、调用方法时自动传入的参数不同。
3.属性(通过方法改造出来)
class Foo(object): def __init__(self): pass @property def start(self): return 1 @property def end(self): return 10 obj = Foo() print(obj.start) print(obj.end) #结果:1 10
总结:
1.编写时
方法上写@property
方法参数:只有一个self
2.调用时:无需加括号 对象.方法
3.应用场景:对于简单的方法,当无需传参且有返回值时,可以使用@property
二.嵌套(建模)
面向对象
class School(object): def __init__(self,name,address): self.name = name self.address = address def speech(self): print("讲课") obj1 = School('老男孩北京校区', '美丽富饶的沙河') obj2 = School('老男孩上海校区', '浦东新区') obj3 = School('老男孩深圳校区', '南山区') class Teacher(object): def __init__(self,name,age,salary): self.name = name self.age = age self.__salary = salary self.school = None t1 = Teacher("李杰",19,158888) t2 = Teacher("雁涛",18,582) t3 = Teacher("alex",18,188888) t1.school = obj1 t2.school = obj2 t3.school = obj3 print(t1.school.name) print(t1.school.address) print(t1.name) print(t1.age) t1.school.speech() #结果: 老男孩北京校区 # 美丽富饶的沙河 # 李杰 # 19 # 讲课
准则: 字段和方法的归类.