python笔记 - day8
参考:
大纲
面向对象三大特性之多态
类成员之静态字段和普通字段
类成员之普通方法和静态方法以及类方法
类成员之属性
类成员之成员修饰符
类成员之特殊成员
其他之isinstance和issubclass
其他之super的应用
实例之自定义有序字典
单例模式
基本异常处理
异常类型
主动触发异常
自定义异常和断言
JAVA和C#不支持多态(几种编程语言多态形式对比)。
字段:
普通字段保存在对象里面,静态字段保存在类里面。
访问普通字段,静态字段规则,方法:
一般情况,自己访问自己字段
规则:
普通字段只能用对象访问
静态字段用类访问(万不得已可以使用对象访问)
class Province: country = "中国" #静态字段 def __init__(self,name): self.name = name #普通字段 hn = Province("河南") hb = Province("河北") sd = Province("山东") db = Province("黑龙江") print(hn.name)
class Province:
country = "中国"
def __init__(self,name):
self.name = "alex"
hn = Province("河南")
print(hn.name)
#通过类访问静态字段,推荐
print(Province.country)
#通过对象访问静态字段,不推荐
print(hn.country)
class Provice:
country = "中国"
def __init__(self,name):
self.name = "alex"
print(Province.country)
#静态字段,在代码加载时,已经创建;
class Province: country = "中国" def __init__(self,name): self.name = name #普通方法,由对象去调用执行(方法属于类) def show(self): #print(self.name) print(123) @staticmethod def f1(arg1,arg2): #静态方法,由类直接调用执行 print(arg1,arg2) @classmethod def f2(cls): cls #类名,加()创建对象 print(cls) Province.f1(1,2) #静态方法,由类直接调用执行 Province.f2() #不用传值,自动传值 所有方法属于类: 1.普通方法:至少一个self, 对象执行 2.静态方法:任意参数, 类来执行(也可以对象执行,不推荐) 3.类方法:至少一个cls 类执行(也可以对象执行,不推荐)
分页:不使用属性;
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 p = Pager(101) #不使用人妖,属性 #p.all_count #字段 result = p.all_pager()#方法 print(result)
使用属性,人妖,@property,:
使用属性实现的效果功能是:通过对象执行方法,不用加括号了。
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
def all_pager(self,value):
print(value)
@all_pager.deleter
def all_pager(self):
print("del all_pager")
#通过@property执行方法,不用加括号了;
p = Pager(101)
ret = p.all_pager
print(ret)
# #给属性重新赋值,加变量
res = p.all_pager = 111
print(res)
# #删除属性
del p.all_pager
属性定义:
1.不伦不类的东西
2.具有方法的写作形式,具有字段的访问方式;
3.属性只是提供的是访问方法,具体做什么靠自己定义。
属性存在的第二种方式:
class Pager:
def __init__(self,all_count):
self.all_count = all_count
def f1(self):
return 123
def f2(self,value):
print(value)
def f3(self):
print("del p.foo")
foo = property(fget=f1,fset=f2,fdel=f3)
p = Pager(101)
result = p.foo
print(result)
p.foo = "alex"
del p.foo
属性一:
属性二:
属性存在的第二种方式:
成员修饰符:
私有: 只能类自己本身成员内部可以访问
公有:
class Foo: 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() obj.f1() 上面这个例子:不能通过f2调用私有方法,只能通过本身f1调用私有方法,结论:私有方法只能通过内部调用;
class Fzz:
__cc = "123"
def __init__(self,name):
self.__name = name
def f1(self):
print(self.__name)
# def f3(self):
# print(Fzz.__cc)
#通过静态字段方法来执行
@staticmethod
def f3():
print(Fzz.__cc)
# print(Fzz.__cc) #调用不到cc方法
obj = Fzz('dddd')
obj.f3()
#能够调用到cc的方法
Fzz.f3()
#通过静态字段方法来执行
内置方法:
class Foo: def __init__(self,name,age): self.name = name self.age = age def __del__(self): pass def __call__(self, *args, **kwargs): print("call") def __str__(self): return "%s - %d"%(self.name,self.age) obj = Foo('alex',18) obj() #对象,执行call方法
Foo('alex',18)() #执行类方法并且执行call方法;(这么写) #类加括号执行__init__方法 #对象加括号执行call方法 #这里应用的__str__方法,不用__str__方法,输出的是内存地址 obj1 = Foo('alex',73) obj2 = Foo('eric',84) print(obj1) print(obj2)
class Foo: def __init__(self,name,age): self.name = name self.age = age 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') obj1 = Foo('alex',73) #获取对象中封装的数据,获取数据类型是字典 ret = obj1.__dict__ print(ret,type(ret)) #执行__getitem__ ret = obj1['test'] print(ret) #执行__setitem__ res = obj1['k1'] = 111 print(res) #执行__delitem__ del obj1['k1']
class Foo: def __init__(self,name,age): self.name = name self.age = age def __str__(self): return "%s - %d"%(self.name,self.age) def __getitem__(self, item): print(type(item)) print(item.start) print(item.stop) print(item.step) return 123 def __setitem__(self, key, value): print(type(key),type(value)) print(key.start) print(key.stop) print(key.step) def __delitem__(self, key): print(type(key)) #执行__str__ obj1 = Foo('alex',73) print(obj1) #执行__getitem__ ret2 = obj1[1:3:2] print(ret2) #执行__setitem__ ret3=obj1[1:4] = [11,22,33,44,66] print(ret3) #执行__delitem__ del obj1[1:4]
class Foo: def __iter__(self): yield 1 yield 2 obj = Foo() for item in obj: print(item) #原理:把iter的值,返回给obj
类和类,类和对象之前的关系检测
class Bar: pass class Foo(Bar): pass obj = Foo() ret = isinstance(obj,Foo) res = isinstance(obj,Bar)#因为Foo继承了Bar,这里也为true print(ret) print(res) #isinstance:判断这个类,是否属于这个对象 ret1=issubclass(Foo,Bar) print(ret1) #issubclass:判断Foo是否是Bar的子类;
super()
#这个程序执行半天也不行,必须用python3执行 class C1: def f1(self): print("c1.f1") class C2(C1): def f1(self): #主动执行父类的f1方法 super(C2,self).f1() print("c2.f1") #方法二:执行C1的f1,python2也可以(不建议用); # C1.f1(self) obj = C2() obj.f1()
结果:执行super(C2,self).f1()后,执行print("c2.f1");
有序字典
class MyDict(dict): def __init__(self): self.li = [] super(MyDict,self).__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)
设计模式(重要),单例模式,最基础的
class Foo: instance = None def __init__(self,name): self.name = name @classmethod def get_instance(cls): #cls是类名 if cls.instance: return cls.instance else: obj = cls('alex') cls.instance = obj return obj obj1 = Foo.get_instance() print(obj1) obj2 = Foo.get_instance() print(obj2) #内存地址都是一样的
主动触发错误:
try: raise ValueError('主动错误一下') #self.message = '主动错误一下' print(123) except ValueError as ex: print(ex) #str except Exception as ex: print(ex) #__str__,return self.message else: pass
异常处理,异常类型:
while True: num1 = input("num1:") num2 = input("num2:") try: li = [] li[100] num1 = int(num1) num2 = int(num2) result = num1 + num2 except Exception as ex: print(ex) #输出的类型是str except ValueError as ex: print(ex) except IndexError as ex: print(ex)
finally(都会执行):
try: li = [] li[100] except IndexError as ex: print(ex) #str except Exception as ex: print(ex) else: pass finally: print("上面的条件成立,不成立,都执行finally")