标签:
多态:多种形态、多种类型
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: pass class B(A): pass class 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) @classmethod def f2( cls ): #类方法的参数,最少得有一个cls。 pass @classmethod def 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_pager p.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.foo print (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() # 对象() 执行call Foo()() # 与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‘] = 111 del 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 1 yield 2 obj = 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 ret obj = 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_str obj = MyDict() obj[ ‘k1‘ ] = 123 obj[ ‘k2‘ ] = 456 print (obj) |
标签:
原文地址:http://www.cnblogs.com/yangruizeng/p/5635630.html