标签:
多态:多种形态、多种类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | def func(arg):print(arg)func(1)func("alex")func([11,22,33]])c#/Java #java定义方法时,int arg,传参时就只能是int类型。如果想用多态就需要类的继承def func(int arg):print(arg)func(123)func("alex") #报错class A:passclass B(A):passclass C(A):pass#arg参数:必须是A类型或A的子类类型def func(A arg):print(arg)#obj = B()#obj = C()obj = A()func(obj) |
类的成员简介:
字段
静态字段
普通字段
#提示:静态字段在代码加载时已经创建。
方法(所有的方法属?于类)
普通方法: 至少一个self,通过对象去执行
静态方法: 任意参数,类执行
类方法: 至少一个cls, 由类执行
属性
具有方法的写作形式,具有字段的访问形式
class Province:
country = "中国"
静态字段
1 2 3 | def __init__(self, name): self.name = name#self.country = ‘中国‘ #如果把country放到此处,每个对象都会放个中国,太占内存,故把大家都有的放到类中,静态字段。 |
动态字段,
一般情况:自己访问自己字段
静态字段,通过类访问也行,通过对象访问也行:
规则:
普通字段用对象访问
静态字段用类访问(万不得已的时候可以使用对象访问)
1 2 3 4 5 6 7 | print(hn.country)print(Province.country)hn = Province(‘河南‘)hb = Province(‘河北‘)sd = Province(‘山东‘)db = Province(‘黑龙江‘) |
静态方法:
1 2 3 4 5 | class Province: country = "中国" def __init__(self,name): self.name = name |
普通方法,由对象去调用执行(方法属于类)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | def show(self): #print(self.name) print(123) @staticmethod #静态方法需要加此项 def f1(arg1,arg2):#静态方法通过类直接就可以调用了,不需要对象 #静态方法,由类调用执行 print(arg1,arg2)@classmethoddef f2(cls): #类方法的参数,最少得有一个cls。pass@classmethoddef f3(cls,a1,a2) |
类方法,参数不需要传递,自动传递传递类名。
类方法比静态方法唯一多的一点是自动传递类名, 如果传递参数了,就会根据传入的内容来赋值。
普通方法:对象直接调用,参数最少有个self
静态方法:需要@staticmethod, 一般建议用类名调用,对象也能调用,不过不推荐。
类方法: 需要@classmethod, 与静态方法唯一的区别在于参数cls,python会自动传值(类名)
Province.f1(111,222)
#静态方法与普通函数没有区别,放在类中,是说明这个函数与这个类的功能有关,方便管理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | class Pager: def __init__(self, all_count): self.all_count = all_count @property #取值调用这个 def all_pager(self): a1, a2 = divmod(self.all_count, 10) if a2 == 0: return a1 else: return a1 + 1 @all_pager.setter #p.all_pager = 111 赋值时会调用这个 def all_pager(self, value): print(value) @all_pager.deleter #使用del p.all_pager方法时会调用这个 def all_pager(self): print(‘del all_pager‘)p = Pager(111)# print(p.all_count)# ret = p.all_pager# print(ret)# p.all_pager = 111# print(p.all_pager)del p.all_pagerp.all_pager = 111 #想使用这个,就需要@all_pager.setter属性的另一种格式:class Pager: def __init__(self, all_count): self.all_count = all_count def f1(self): return 123 def f2(self, value): pass def f3(self): pass foo = property(fget=f1, fset=f2, fdel=f3)p = Pager(101)result = p.fooprint(result)p.foo = "alex"del p.foo |
私有:
只能类自己本身成员内部可以访问, 前边加两个下划线即为私有。如: __cc
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | class Foo: __cc = 111 def __init__(self, name): self.__name = name def f1(self): print(self.__name) @staticmethod def f3(): print(Foo.__cc)# print(Foo.__cc) #不能调用, __为私有,外部不能访问# Foo.f3() #可以调用,调用Foo的静态方法f3,f3可以调用私有字段。obj =Foo(‘yangrz‘)# print(obj.__name) #不恩那个调用,同样__name为私有方法# obj.f1() #可以调用,f1方法调用私有字段###############################################################class Foo: __cc = "123" def __init__(self, name): self.__name = name def f1(self): print(self.__name) @staticmethod def f3(): print(Foo.__cc)print(Foo.__cc)obj = Foo(‘ddd‘)obj.f3()#f3如果是非静态方法,需要通过对象去调用。Foo.f3() #f3静态方法,可以直接通过类调用。class Foo: __cc = "123" def __init__(self, name): self.__name = name def f1(self): print(self.__name) class Bar(Foo): def f2(self): print(self.__name) #obj = Bar("alex") #obj.f2() #Bar虽然继承Foo类,但是Bar.f2方法是无法调用内部的字段的#obj.f1() #Bar继承Foo类,obj.f1回去找Foo类中的f1,属于内部,所以会输出结果。#私有的,内部能调用,外部不能调用外部访问强制访问私有成员的方法:(不到万不得已,不要访问)_类名__xxxxx(方法)obj = Foo(‘alex‘)print(obj_Foo__xxxx) |
__init__
__doc__
__call__
__setitem__
...
析构方法:
1 2 3 4 5 | __del__(self) 在对象被内存回收之前执行的。__call__(self) obj = Foo()obj() #对象后边加括号,执行__call__方法class Foo: |
构造方法
1 2 3 | def __init__(self, name, age): self.name = name self.age = age |
析构方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | def __del__(self): pass def __call__(self): print(‘call‘) def __str__(self): return "%s - %d" %(self.name, self.age)obj = Foo(‘didi‘, ‘didi‘)obj() # 对象() 执行callFoo()() # 与obj()效果一样obj1 = Foo(‘alex‘, 74)obj2 = Foo(‘eric‘, 98)#print(obj1) #print对象名会返回__str__方法里定义的#print(obj2)ret = str(obj1)print(ret)obj.__dict__:class Foo: |
构造方法
1 2 3 | def __init__(self, name, age): self.name = name self.age = age |
析构方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | ef __del__(self): pass def __call__(self): print(‘call‘) def __str__(self): return "%s - %d" %(self.name, self.age)obj1 = Foo(‘alex‘, 74)obj2 = Foo(‘eric‘, 98)ret = obj1.__dict__print(ret)#执行结果:#{‘name‘: ‘alex‘, ‘age‘: 74} |
各种item:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | class Foo: # 构造方法 def __init__(self, name, age): self.name = name self.age = age # 析构方法 def __del__(self): pass def __call__(self): print(‘call‘) def __str__(self): return "%s - %d" %(self.name, self.age) def __getitem__(self, item): return 123 def __setitem__(self, key, value): print(‘setitem‘) def __delitem__(self, key): print(‘del item‘)# dic = {‘k1‘:123} #dic = dict(k1=123)# dic[‘ke1‘] #dic{}# dic[‘k1‘] = 123# del dic[‘k1‘]obj = Foo(‘alex‘, 74)# obj() #call# 语法对应关系# ret = obj[‘ad‘]# print(ret)# obj[‘k1‘] = 111del obj[‘k1‘] |
切片模式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | class Foo: def __getitem__(self, item): # print(type(item), item) # 以切片格式取值时,这里的类型是slice # item.start # 获取切片的起始位置 # item.stop # 获取切片的结束位置 # item.step # 获取切片的步长 print(type(item)) return 123 def __setitem__(self, key, value): # key.start key.stop key.step print(type(key), type(value)) def __delitem__(self, key): # key.start key.stop key.step print(type(key))obj = Foo(‘alex‘, 73)# obj() #call# 语法对应关系# ret1 = obj[‘ad‘]ret2 = obj[1:4:2]obj[1:4] = [11, 22, 33, 44, 66]del obj[1:4] |
__iter__方法:
1 2 3 4 5 6 7 8 9 | class Foo: def __iter__(self):yield 1yield 2obj = Foo()for item in obj:print(item) |
当执行for循环的时候,会自动去找__iter__方法,__iter__方法会返回一个生成器,
然后for去循环这个可循环的返回值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | - isinstance #看是不是一个类的方法, 如果是子类的对象,那么,也是父类的对象- issubclass #看一个类是不是一个类的子类,是不是继承父类。class C1: def f1(self): print(‘c1.f1‘) return 123 class C2(C1): def f1(self): # 主动执行父类的f1方法 ret = super(C2, self).f1()# 这里也可以使用C1.f1(self)来执行父类的方法,不推荐使用 print( ‘c2.f1‘) return retobj = C2()obj.f1() |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | class MyDict(dict): # 继承dict类 def __init__(self): self.li = [] # 创建一个空列表,用于将字典中的各个key,放到列表 super(MyDict, self).__init__() # 执行原字典中的init方法 def __setitem__(self, key, value): self.li.append(key) super(MyDict,self).__setitem__(key, value) def __str__(self): temp_list = [] for key in self.li: value = self.get(key) temp_list.append("‘%s‘:%s" %(key, value)) temp_str = "{" + ",".join(temp_list) + "}" return temp_strobj = MyDict()obj[‘k1‘] = 123obj[‘k2‘] = 456print(obj) |
标签:
原文地址:http://www.cnblogs.com/yangruizeng/p/5635630.html