标签:
1. 类的成员:
1) 字段 : 普通字段、静态字段;
2) 方法 : 普通方法、静态方法、类方法;
3) 属性 : 普通属性(获取、设置、删除);
2. 成员修饰符:
1)公有的 任何 都可以调用;
2)私有的 仅类自己内部可以调用;可以用一个另类的方法调用,就是 obj._类名__私有(字段等),好吧,知道能这么用就行了,最好忘了它。
3. 类的特殊成员:
__init__ 构造方法;
__dic__ 注释文档查看,函数下加引号写的第一位置,会被此成员读取;
__call__ 变量加括号执行call方法;
__str__ 将内存地址的内容,读取成str内容;
__setitem__
......
4. 面向对象的其它内容:
-- isinstance 判断一个对象是否属于某个类;
-- issubclass 判断一个类是否属于某个类的子类;
-- 执行父类构造方法
-- 应用:
自定义类型,对字典进行补充,有序字典,源码的扩展;
5. 设计模式之单例模式;
6. 异常处理:
try === except === = finally
1. 普通字段,实例:
class Foo: def __init__(self,name): self.name = name
代码解析:
name就是普通字段,当Foo函数,被实例化时,如:obj = Foo(‘hailong‘) ,对象obj 就使用了name普通字段,普通字典默认被对象使用,所以普通字段是保存在对象里的;
2. 静态字段,实例:
class Province: country = "中国" # 静态字段,保存在类里,节省内存空间; def __init__(self,name): self.name = name country = Province.country tj = Province("天津") print(tj.country ,‘\t‘,country)
代码解析:
country是静态字段,如上实例所示,静态字段,类可以调用,对象也可以调用,其它语言里是不允许的,之所以对象可以调用静态字段,是因为对象里的类对象指针(对象去数据时,是先从自己本身找,找不到,通过类对象指针到类里找)通过这种方式来访问的;通常情况下,我们要使用类来调用静态字段;
总结:
普通字段,用对象来访问; 静态字段,使用类来访问,实在没办法时才用对象访问;
当执行程序时,如果没创建对象时,普通字段不会加载到内存,但是静态字段默认会加载到内存;
1. 普通方法,实例:
class Province: country = "中国" def __init__(self,name): self.name = name def show(self): # 方法属于类,是由对象调用的 print(self.name) tj = Province("天津") tj.show()
代码解析:
方法属于类,普通方法存在类里,是由对象调用的;
2. 静态方法,实例:
class Province: country = "中国" # 静态字段,保存在类里,节省内存空间; def __init__(self,name): self.name = name @staticmethod # 静态方法,是由类调用的 def func(arg1,arg2): print(arg1,arg2) Province.func(123,‘qcc‘)
代码解析:
静态方法是由类调用的,就是方法去掉self参数后,是用装饰器staticmethod,传参自定义,不需要创建对象,就可以执行的方法。用于一些不通用的方法,这样节省内存空间;
相当于Python的函数;
3. 类方法,实例:
class Province: country = "中国" # 静态字段,保存在类里,节省内存空间; def __init__(self,name): self.name = name @classmethod def f1(cls): print(cls) Province.f1()
代码解析:
类方法是由类调用的,它有一个默认的形式参数cls,cls相当于类名;
1. 普通属性,实例:
class Pager: def __init__(self,count_pager): self.count_pager = count_pager @property # 普通属性 def all_pager(self): a1,a2=divmod(self.count_pager,10) if a2 == 0: return a1 return a1+1 p = Pager(101) print(p.all_pager) # 执行普通属性,不用加括号了
代码解析:
普通属性,具有方法的访问写形式,具有字段的访问形式。 相当于方法去掉括号,由对象调用;
2. 属性操作(设置)实例:
class Pager: def __init__(self,count_pager): self.count_pager = count_pager @property def all_pager(self): a1,a2=divmod(self.count_pager,10) if a2 == 0: return a1 return a1+1 @all_pager.setter def all_pager(self,value): print(value) p = Pager(101) p.count_pager = 211 # 设置属性,对属性的方法进行setter; print(p.count_pager)
代码解析:
对象生成后,count_pager 根据类参数定义一个值,当想要使用一个新值时,需要使用到设置属性,给字段count_pager重新赋值,使用普通属性方法setter装饰器,重新给字段赋值;
3. 属性操作(删除)实例:
class Pager: def __init__(self,count_pager): self.count_pager = count_pager @property def all_pager(self): a1,a2=divmod(self.count_pager,10) if a2 == 0: return a1 return a1+1 @all_pager.setter def all_pager(self,value): print(value) @all_pager.deleter def all_pager(self): print("del all_pager") p = Pager(101) p.count_pager = 211 #设置方法,会调用all_pager.setter下的方法; print(p.count_pager) del p.all_pager # del 是个语法,会调用all_pager.deleter下的方法;
property的构造方法中有个四个参数
对象.属性
时自动触发执行方法对象.属性 = XXX
时自动触发执行方法del 对象.属性
时自动触发执行方法对象.属性.__doc__
,此参数是该属性的描述信息class Pager: def __init__(self,name): self.name = name def f1(self): return 123 def f2(self,value): print(value) def f3(self): print(‘del f1‘) # 还没弄明白,具体怎么用 foo = property(fget=f1,fset=f2,fdel=f3) obj = Pager(‘hailong‘) res = obj.foo print(res) obj.foo = 456 del obj.foo
代码解析:
不用加装饰器了,直接给静态字段赋值,使用property,来完成属性的功能;
由属性的定义和调用要注意一下几点:
注意:属性存在意义是:访问属性时可以制造出和访问字段完全相同的假象
属性由方法变种而来,如果Python中没有属性,方法完全可以代替其功能。
1. 公有的,实例:
class Province(object): def __init__(self,name): self.name = name hb = Province("河北") print(hb.name) #name是公有的,任何对象都可以调用;
代码解析:
这个例子里,name就是公共的,任何基于Province创建的对象都能使用;
2. 私有修饰符,实例(一):
class Province(object): def __init__(self,name): self.__name = name def f1(self): print(self.__name) hb = Province("河北") hb.f1() # print(hb.__name) # 报错 AttributeError: ‘Province‘ object has no attribute ‘__name‘
代码解析:
当把公有的,加上双下划线后,就变成私有的了,这时外部不能调用,只能是类里的方法可以调用;只有自己访问可以,不能被继承;
实例(二):
class Province(object): __paw = 123 def __init__(self,name): self.__name = name def f1(self): print(Province.__paw) @staticmethod def f2(): print(Province.__paw) hb = Province("河北") hb.f1() # 通过变量调用使用了私有字段的方法; Province.f2() #直接用类调用,静态方法里的私有字段; hb.f2() # 也可以成功,但是不建议这样使用; Province.f1() # 不可以在外部直接使用类里的私有字段,报错 TypeError: f1() missing 1 required positional argument: ‘self‘
上文介绍了Python的类成员以及成员修饰符,从而了解到类中有字段、方法和属性三大类成员,并且成员名前如果有两个下划线,则表示该成员是私有成员,私有成员只能由类内部调用。无论人或事物往往都有不按套路出牌的情况,Python的类成员也是如此,存在着一些具有特殊含义的成员,详情如下:
1. del、call 和 str方法:
class Foo(object): instance = None 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 - %s" % (self.name,self.age) obj = Foo("hailong",23) obj1 = Foo("eric",23) print(obj) # 执行时,调用了str方法 res = str(obj1) # 执行时,调用了str方法 obj() # 变量加括号,执行call方法; Foo("hailong",23)() # 类执行,加括号执行call方法; print(obj1)
2. add 、 dict 方法:
class Foo: def __init__(self,name,age): self.name = name self.age = age def __add__(self, other): temp = "%s - %d" % (self.name,other.age) return temp obj1= Foo("hailong",23) obj2= Foo(‘eric‘,19) res = obj1 + obj2 # 执行add方法; print(res) print(obj1.__dict__) # 返回obj1封装的内容,字典格式输出;
如果执行 类.__dict__ 会打印出类里封装的所有的成员,一般用于对象的封装查看;
3. getitem、setitem和delitem方法:
class Foo: def __init__(self,name,age): self.name = name self.age = age def __getitem__(self, item): return 123 def __setitem__(self, key, value): print(key,value) def __delitem__(self, key): print("del %s" % key) obj1= Foo("hailong",23) res = obj1[‘abc‘] # 执行getitem方法 print(res,"----") obj1[‘k1‘] = 122 # 执行了setitem方法 ,执行结果是k1 122 print(obj1.__dict__) # obj1没有任何改变; del obj1[‘k1‘] # 执行delitem方法,
对象后加括号执行call方法,加上中括号执行 getitem方法。。。
4. getitem 切片方法:
class Foo: def __init__(self,name,age): self.name = name self.age = age def __getitem__(self, item): print(item.start) print(item.stop) print(item.step) return 123 def __setitem__(self, key, value): print(key,value) obj1= Foo("hailong",23) # res = obj1[‘abc‘] # 字符串方法没有切片start等位置属性; res1 = obj1[0:4:2]
5. iter 迭代 方法:
用于迭代器,之所以列表、字典、元组可以进行for循环,是因为类型内部定义了 __iter__
class Foo: def __init__(self,name,age): self.name = name self.age = age def __iter__(self): # iter方法 return iter([11,22,33,44]) # 可迭代类型; obj = Foo("hailong",23) for item in obj: print(item)
for循环,例子二:
class Foo: def __init__(self,name,age): self.name = name self.age = age def __iter__(self): yield 1 yield 2 obj = Foo("hailong",23) for item in obj: print(item)
6. __module__ 和 __class__
__module__ 表示当前操作的对象在那个模块
__class__ 表示当前操作的对象的类是什么
1. isinstance 和 issubclass 内置变量;
class Foo: pass class Func(Foo): pass obj = Foo() res = isinstance(obj,Foo) # obj 是 基于Foo类创建的,返回True; print(res) ret = issubclass(Func,Foo) # Func 类是 Foo类的一个子类,返回True; print(ret)
2. 执行父类构造方法;
如何执行,看实例:
class Foo: def f1(self): print("Foo.f1") class Func(Foo): def f1(self): super(Func,self).f1() print(‘Func.f1‘) obj = Func() res = obj.f1() # obj 执行的了自己的f1方法也执行了父类里的f1方法,因为有super;
这个方法应用于:当想要使用其它程序的功能或框架里的方法时,继承框架或功能的类方法,使用super就能使用框架的功能了;
3. 有序字典:
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_li = [] for key in self.li: value = self.get(key) temp_li.append("‘%s‘:%s" %(key,value)) temp_str = "{" + ",".join(temp_li) + "}" return temp_str obj = Mydict() obj[‘k1‘] = 123 obj[‘k2‘] = 456 print(obj)
代码解析:
继承字典的类,将正常生成字典的key,添加到一个空列表,通过自定义类型对字典的生成过程重新定义,将无序存储的字典,写成一个列表,根据字符串拼接的方法,读取成有序的字典;
用来创建单个实例,什么时候用? 不管获取多少个实例,他们的内存地址是一样的;
class Foo: instance = None def __init__(self,name): self.name = name @classmethod def get_instance(cls): if cls.instance: return cls.instance else: obj = cls(‘hailong‘) cls.instance = obj return obj obj1 = Foo.get_instance() obj2 = Foo.get_instance() # 不管获取多少个实例,他们的内存地址是一样的; print(obj1,obj2) # 两个对象内存地址相同;
try --->except try内容如果不报错,永远不会执行except的内容;
1、异常基础
在编程过程中为了增加友好性,在程序出现bug时一般不会将错误信息显示给用户,而是现实一个提示的页面,通俗来说就是不让用户看见大黄页!!!
try: pass except Exception,ex: pass
需求:将用户输入的两个数字相加
while True: num1 = input(‘input num1:‘) num2 = input(‘input num2:‘) try: num1 = int(num1) num2 = int(num2) result = num1 + num2 try: print(result) except NameError as A: print(A) except Exception as E: print(E)
2、异常种类
python中的异常种类非常多,每个异常专门用于处理某一项异常!!!
1) 常用异常:
AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x IOError 输入/输出异常;基本上是无法打开文件 ImportError 无法引入模块或包;基本上是路径问题或名称错误 IndentationError 语法错误(的子类) ;代码没有正确对齐 IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5] KeyError 试图访问字典里不存在的键 KeyboardInterrupt Ctrl+C被按下 NameError 使用一个还未被赋予对象的变量 SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了) TypeError 传入对象类型与要求的不符合 UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量, 导致你以为正在访问它 ValueError 传入一个调用者不期望的值,即使值的类型是正确的
对于特殊处理或提醒的异常需要先定义,最后定义Exception来确保程序正常运行。
2)另一种结构的异常:
try: # 主代码块 pass except KeyError as ex: # 异常时,执行该块 pass else: # 主代码块执行完,执行该块 pass finally: # 无论异常与否,最终执行该块 pass
3) 主动抛出异常:
try: raise Exception(‘错误了。。。‘) except Exception as ex: print(ex)
4) 自定义异常:
class WupeiqiException(Exception): def __init__(self, msg): self.message = msg def __str__(self): return self.message try: raise WupeiqiException(‘我的异常‘) except WupeiqiException as e: print(e)
5)断言
# assert 条件 assert 1 == 1 assert 1 == 2
条件成立执行,不成立就不执行;
________________________________________________________END____________________________________________________
标签:
原文地址:http://www.cnblogs.com/liuhailong-py-way/p/5624127.html