一、类成员
1、字段
1 class Province: 2 country = '中国' # 实例 (静态) 字段;类变量. 不属于对象, 对象可以访问 3 4 def __init__(self, name): 5 self.name = name # 普通字段 6 7 obj = Province('河北省') # 直接访问普通字段 8 print obj.name 9 10 Province.country # 直接访问静态字段 11 obj.country = "澳大利亚" # 注意。 这里和类变量没由一毛钱关系, 给alex单独加一个属性叫country = ”澳大利亚“ 12 print(obj.country) # 澳大利亚 # 拿到的是自己的。成员实例变量 字段 13 # 总结:类变量,用类名去操作. 规范.
由上图可是:静态字段在内存中只保存一份;普通字段在每个对象中都要保存一份
2、方法 -- 普通方法、静态方法和类方法,三种方法在内存中都归属于类,区别在于调用方式不同
普通方法:由对象调用;至少一个self参数;执行普通方法时,自动将调用该方法的对象赋值给self;
类方法:由类调用; 至少一个cls参数;执行类方法时,自动将调用该方法的类复制给cls;
静态方法:由类调用;无默认参数;
1 class Person: 2 3 def __init__(self): 4 pass 5 # 实例方法需要传递类的对象 self 6 def think(self): 7 print("人能思考") 8 9 # 静态方法不需要传递对象或者类 10 @staticmethod # 静态方法 11 def jisuan(a, b): 12 print("我来过这里") 13 return a + b 14 15 # 类方法: 第一个参数传递的是类名 16 @classmethod 17 def clsMethod(cls): # cls表示的类 18 p = cls() # 可以动态的创建对象. 19 print("我是一个类方法", p) 20 21 22 # p = Person() 23 # p.think() 24 # 25 # Person.think(p) 26 27 # 静态方法的调用: 28 29 # c = Person.jisuan(1, 2) # 类名可以访问 30 # print(c) 31 # 32 # p = Person() 33 # d = p.jisuan(3, 5) # 用对象也可以访问 34 # print(d) 35 36 # 记住, 静态的内容用类名访问 37 38 Person.clsMethod() # 类方法默认第一个参数接收的是类名 39 40 相同点:对于所有的方法而言,均属于类(非对象)中,所以,在内存中也只保存一份。 41 不同点:方法调用者不同、调用方法时自动传入的参数不同。
3、属性
(1) 属性的基本使用
1 # ############### 定义 ############### 2 class Foo: 3 4 def func(self): 5 pass 6 7 # 定义属性 8 @property 9 def prop(self): 10 pass 11 # ############### 调用 ############### 12 foo_obj = Foo() 13 14 foo_obj.func() 15 foo_obj.prop #调用属性 16 17 属性的定义和使用
由属性的定义和调用要注意一下几点:
-
定义时,在普通方法的基础上添加 @property 装饰器;
-
定义时,属性仅有一个self参数
-
调用时,无需括号方法:foo_obj.func()属性:foo_obj.prop
注意:属性存在意义是:访问属性时可以制造出和访问字段完全相同的假象
属性由方法变种而来,如果Python中没有属性,方法完全可以代替其功能。
实例:对于主机列表页面,每次请求不可能把数据库中的所有内容都显示到页面上,而是通过分页的功能局部显示,所以在向数据库中请求数据时就要显示的指定获取从第m条到第n条的所有数据(即:limit m,n),这个分页的功能包括:
-
根据用户请求的当前页和总数据条数计算出 m 和 n
-
根据m 和 n 去数据库中请求数据
1 # ############### 定义 ############### 2 class Pager: 3 4 def __init__(self, current_page): 5 # 用户当前请求的页码(第一页、第二页...) 6 self.current_page = current_page 7 # 每页默认显示10条数据 8 self.per_items = 10 9 10 11 @property 12 def start(self): 13 val = (self.current_page - 1) * self.per_items 14 return val 15 16 @property 17 def end(self): 18 val = self.current_page * self.per_items 19 return val 20 21 # ############### 调用 ############### 22 23 p = Pager(1) 24 p.start 就是起始值,即:m 25 p.end 就是结束值,即:n
二、类成员的修饰符
公有成员,在任何地方都能访问
私有成员,只有在类的内部才能方法
1、私有成员
1 class Person: 2 def __init__(self, laopo, mimi): 3 self.__laopo = laopo # 私有的 4 self.__mimi = mimi 5 6 alex = Person("wusir", "他俩搞基") 7 print(alex.__mimi) # 私有的. 谁都不不能碰,会报错
可以 通过这个公共的方法来获取到私有的内容. 这样做的好处是. 外界, 只能看, 但是改不了. 不单单实例变量有私有的. 类变量(静态变量量)一样拥有这样的属性:
1 class Person: 2 __zisi = "人都是自私的" # 人都是自私的. 但是这个自私又不希望别人知道 3 def __init__(self, laopo, mimi): 4 self.__laopo = laopo # 私有的 5 self.__mimi = mimi 6 def gaosuni(self): 7 print("大喇喇叭开始广播了了") 8 return self.__mimi 9 alex = Person("wusir", "他俩搞基") 10 mimi = alex.gaosuni() 11 print(mimi) 12 print(Person.__zisi) # 报错
1 class Person: 2 __zisi = '人都是自私的' 3 def __init__(self, laopo, mimi): 4 self.__laopo = laopo 5 self.__mimi = mimi 6 def gaosuni(self): 7 print('大喇叭开始广播了') 8 return self.__mimi 9 10 alex = Person('wusir', '他俩搞基') 11 mimi = alex.gaosuni() 12 print(mimi) 13 print(Person.__zisi) #报错
2、私有方法
1 class Person: 2 def __init__(self): 3 pass 4 def __yue(self): # __yue是⼀一个私有的⽅方法. 只能在类中⾃自⼰己调⽤用. 类外⾯面不能访问. 5 print('我要约会') 6 def job(self): 7 print('我要工作') 8 9 p = Person() 10 # p.__yue() 报错 11 p.job()
子类无法继承私有方法