python 基础 day8
pickle.load:切记,如果写入文件的是类,一定要先导入相关的类
一、上节回顾补充
二、面向对象(下) 成员
1、字段 2、方法 3、属性
三、成员修饰符
四、特殊成员
五、面向对象边缘
六、异常处理
七、设计模式之单例模式
一、上节回顾补充
面向对象基本知识:
1、类和对象的关系
2、三大特性: 封装、继承、多态(多种形态、多种类型)
多态:
def func(arg): #python中不用指定参数arg类型 print(arg) func(1) #可以三数字 func("alex") #可以三字符串 func([11,22,33,]) #可以三列表
在C#/java中 必须制定参数类型,下面用python的方式举例:
def func(A arg): #必须指定类型 print(arg) func(123) func("alex") #报错(如果不是int类型就报错) class A: pass class B(A): pass class C(A): pass #arg 参数:必须是A类型或A的派生类类型 def func(A arg): #这里必须指定父类A,但arg的类型的类型可以三A、B、C print(arg)
二、面向对象中 成员
字段:
静态字段、普通字段
ps:静态字段在代码加载时已经创建
class foo:
#字段(静态字段)属于类,用类调用
cc = 123
def __init__(self):
#字段(普通的字段)保存在对象里,用对象调用
self.name = 'alex' #如果没有创建对象,那么内存里就没有普通字段
一般情况:自己访问自己的字段
class Province:
country = "中国"
def __init__(self,name):
self.name = name
hn = Province("河南")
hb = Province("河北")
print(hn.name) # 在对象里用对象访问
print(Province.country) # 在类里用类访问
# 在Python里也可以用对象访问静态字段
print(hn.country)
规则:
普通字段只能用对象访问
静态字段用类访问(万不得已不要用对象访问)
方法: 所有方法属于类(在其他语言里只有两种方法)
1、普通方法:至少一个self,对象执行
2、静态方法:任意参数,没有self,类执行
3、类方法:至少有一个cls参数,由类执行
class Province:
country = "中国"
def __init__(self,name):
self.name = name
#普通方法,由对象去调用执行(方法属于类)
def show(self):
print(self.name)
#静态方法,由类调用执行(操作1、2、之后变成静态方法)
@staticmethod #2、加上@staticmethod
def f1(): #1、参数里去掉self,可以有其他参数
print("....")
#类方法(静态方法的一种)
@classmethod
def f2(cls): #至少必须有一个参数cls,自动传递参数返回类名
#cls #类名,()创建对象
#cls()
print(cls) #类名<class '__main__.Province'>
def f3(self):
return self.name[1]
obj = Province("河南")
obj.show()
Province.f1()
Province.f2() #<class '__main__.Province'>
ret = obj.f3()
print(ret) #南
属性:
不伦不类的东西
具有方法的写作形式,具有字段的访问形式
class Page:
def __init__(self,all_count):
self.all_count = all_count
@property #属性就需要加上property这个方法
def all_pager(self):
a1,a2 = divmod(self.all_count,10)
if a2 == 0:
return a1
else:
return a1 + 1
@all_pager.setter #函数名.setter ,设置
def all_pager(self,value): #函数名都和上一个相同
print(value)
@all_pager.deleter # 删除
def all_pager(self):
print("del")
#all_pager没有加上属性之前,用下面形式操作
#p = Page(101)
# r = p.all_count #字段
# result = p.all_pager() #方法
# print(result)
#all_pager加上属性之后
p.all_count = 102
del p.all_count #删除方法的字段
ret = p.all_pager #属性 (属性和方法区别就是少了括号)
print(ret)
p.all_pager = 111 #用属性重新定义
del p.all_pager #用属性删除,伪删除动作,里面执行什么自己定义的
另一种属性
class Pager:
def __init__(self,all_count):
self.all_count = all_count
def f1(self):
return "f1"
def f2(self,value):
print(value)
def f3(self):
print("f3")
foo = property(fget=f1,fset=f2,fdel=f3) #还可以按顺序直接给值
p = Pager(101)
ret = p.foo
print(ret)
obj = Pager(110)
obj.foo = "f2"
del obj.foo
#结果
f1
f2
f3
三、成员修饰符
私有的: 只能类自己本身的成员访问调用,其他类不能访问
公有的: pass
class Foo:
def __init__(self,name,age):
self.__name = name #加两个下划线,只能在类的内部访问,外部访问不到
self.age = age
def f1(self):
print(self.__name)
class Bar(Foo):
def f2(self):
print(self.age) #这里如果写成self.__name则外面获取obj1.f2()会报错
obj = Foo("alex",13)
#print(obj.__name) #会报错,外部不能访问
obj1 = Bar("Q",12)
obj1.f2() #继承也不能执行__name,只能本身类内部访问
obj1.f1()
#print(obj._Foo__name) #(可以取到私有的,不到万不得已不要强制访问)
四、特殊成员
构造方法 __init__
析构方法 __del__ :垃圾清除之前自动执行 类的__del__方法(有就执行没有不执行)
__call__ :对象加括号,就会自动执行__call__方法
__str__:直接打印对象,就会自动执行__str__方法
__getitem__:获取
__setitem__:设置
__delitem__:删除
class F:
#构造方法
def __init__(self,name,age):
self.name =name
self.age =age
#析构方法
def __del__(self):
pass
def __call__(self, *args, **kwargs):
print("123")
def __str__(self):
return "%s" % self.name
def __getitem__(self, item):
# print(item.start)#obj[1:2] 中的1
# print(item.stop)#2
# print(item.step) #步长
return "getitem"
def __setitem__(self, key, value):
#key.star key.stop key.step
return "setitem"
def __delitem__(self, key):
# key.star key.stop key.step
print("del item")
p = F("QL",12)
print(p.__class__) #<class '__main__.F'>
obj = F("QL",15)
#语法对应关系
ret = obj["ad"] # 自动执行getitem方法,自动赋值给item
ret1 = obj[1:2] #切片 会执行getitem方法
print(ret1)
obj[1:4] = [11,22,33,44,55,66,] #自动执行setitem方法
del obj[1:3] #自动执行 delitem
print(obj) #直接打印对象,就会自动执行__str__方法
obj() #对象加括号,就会自动执行__call__方法
# #ret = obj["k1"] = 111 #自动执行setitem方法
# #print(ret)
#
# del obj["k1"] #自动执行delitem方法
obj() #加上__call__方法才能执行(对象后加括号)
#F()() #也可以写成这样
print(obj) #不加str会输出内存地址<__main__.F object at 0x0000000000726630>,加上__str__会友好显示,str里返回什么就输出什么
#__dict__ #获取对象中封装的数据 【重要】
ret = obj.__dict__
print(ret) #{'age': 12, 'name': 'QL'}
#print(F.__dict__)#获取类中的成员
__iter__
class F1():
def __iter__(self): #iter是生成器(里面有yield就是生成器)
#yield 1
#yield 2
return iter([11, 22, 33, ])
obj = F1()
for item in obj:#默认不可以迭代,加上iter方法才可以迭代
print(item)#默认执行iter方法,迭代iter返回值
五、面向对象边缘
- insinstance 查看某个对象是不是某个类创建的
- issubclass 查看某个类是不是某个类的子类
class A:
pass
class B(A):
pass
obj = A()
ret = isinstance(obj,B)
class Bar:
pass
class Foo(Bar):
pass
obj = Foo()
#obj,Bar(obj类型和obj类型的父类)的实例
ret2 = isinstance(obj,Bar) #查看obj是不是Bar创建的
print(ret2) #True
ret1 = issubclass(Bar,Foo)# 查看Bar 是不是Foo的子类
print(ret1) #False
主动执行父类方法:
class C1:
def f1(self):
print("c1.f1")
class C2(C1):
def f1(self):
# # 主动执行父类的f1方法
super(C2,self).f1()
print("c2.f1")
#C1.f1(self) #不建议使用,用上面的super方法
obj1 = C2()
obj1.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) #继承父类的setter
#结果
{'k1': 123, 'k2': 456}
六、异常处理
while True:
num1 = input('num1:')
num2 = input('num2:')
try:
li = [11, 22]
print('li[100]') #indexerro
num1 = int(num1)
num2 = int(num2)
result = num1 + num2
except ValueError as ex: #只捕获ValueError错误 从上往下捕获
print('ex')
except IndexError as ex:
print('ex')
except Exception as ex: # ex 是Exception的一个对象,Exception捕获所有错误
print('ex') # str
完整代码块
try:
pass
except ValueError as ex:
print(ex)
except Exception as ex:
print(ex)
else: #上面不报错执行else
pass
finally: #不管报不报错都执行finally
pass
主动触发异常
try:
raise Exception('主动错误一下') #self.message = '主动错误一下’
print(1234)
except ValueError as ex:
print(ex)
except Exception as ex:#__str__,return self.message
print(ex)
else: #上面不报错执行else
pass
finally: #不管报不报错都执行finally
pass
断言
assert 1==1 #如果条件成立不报错 assert 1==2 #如果条件不成立报错 p = obj() p.start() #在执行start之前先执行一个 p.status == False,就可以在start中写入(assert p.staus == False)
七、设计模式之单例模式(23种,推荐书《goF设计模式》)
单例模式: 用来创建单个实例
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 #对象赋值给instance
return obj
obj1 = Foo.get_instance()
print(obj1)
obj2 = Foo.get_instance()
print(obj2)

谁来访问都创建一个,比较浪费,不如只创建一个,都来访问这一个。
浙公网安备 33010602011771号