一、类和构造方法
class Role(object): # 定义一个类,括号内参数为要继承的父类的名称,object为最顶级的父类,即定义一个类时,必须写object或者其他父类的名称 ac = None # 类变量,只要定义类就存在,是共用的变量,类中的功能要访问这个变量,也必须用self.ac的方法,类变量和实例变量互不影响 def __init__(self,name,role,weapon,life_value): # 初始化类中的变量,可以被类中的方法调用 self.name = name # 实例变量,只有实例化对象时,变量才会存在 self.role = role self.weapon = weapon self.life_value = life_value # self.后的变量名可以自己定义,不需要和__init__()中的参数名相同 def but_weapon(self,weapon): # 在类中定义一个功能,功能函数在类所在内存中,实例化对象时不实例化功能函数,实例化对象访问功能函数时,是访问的类的内存地址 print("%s is buying [%s]" %(self.name,weapon)) # 定义的功能中,要引用类中的初始化变量,引用的是self.变量名 self.weapon = weapon # 可以改变类中的变量 Role.shoes = 'China Brand' # 直接这样调用类,相当于给该类添加了一个类变量 p1 = Role('zhu','police','B10',100) # 定义类的一个实例化对象,初始化的变量存在于实例中 t1 = Role('zhang','terrorist','B11',100) print(p1.shoes) # 直接这样调用,相当于调用的是类中的变量 print(t1.shoes) p1.shoes = 'US Brand' # 调用之后给它赋值,相当于在这个实例中定义了一个变量,再访问时是访问的自身的变量,和类变量无关 print(p1.shoes) print(t1.shoes) p1.but_weapon('AK47') # 对象可以访问类中的功能 t1.but_weapon('B51') print('%s have [%s]' %(p1.name,p1.weapon)) # 对象可以访问各自类中的变量 print('%s have [%s]' %(t1.name,t1.weapon))
China Brand
China Brand
US Brand
China Brand
zhu is buying [AK47]
zhang is buying [B51]
zhu have [AK47]
zhang have [B51]
二、类的继承
一个类可以接收另一个类的变量属性、方法等
class CartoonMember(object): num = 0 def __init__(self,name,age,sex): self.name = name self.age = age self.sex = sex self.enroll() # 实例化时会自动调用类中的这个方法 def enroll(self): CartoonMember.num += 1 # 每加入一个人,类变量num都加1,不能写成self.num,这样写是为实例加入一个变量num print("Welcome to this cartoon,[%s],now we have [%s] member!" %(self.name,CartoonMember.num)) # 这种情况下也可以写成self.num,因为实例化时调用的是父类的同一个变量 def tell(self): print("Hello,my name is [%s]" %self.name) class Police(CartoonMember): # 要继承哪个类,把类名字作为参数写入 def __init__(self,name,age,sex,job,salary): # 如果不写__init__()方法,默认继承的是父类的__init__()方法,但子类有自己扩展的东西,所以要自己写一个,这样写会把父类__init__()中的变量重新写一遍,即覆盖父类的__init__() super(Police, self).__init__(name,age,sex) # 所以需要这样写重新继承父类的__init__(),避免覆盖父类,经典类写法是SchoolMember.__init__(self,name,age,sex) self.job = job self.salary = salary def doing(self): print("[%s] is a [%s]." %(self.name,self.job)) class Student(CartoonMember): def __init__(self,name,age,sex,hobby): super(Student, self).__init__(name,age,sex) self.hobby = hobby def self_hobby(self): print("Student [%s] like [%s]." %(self.name,self.hobby)) p1 = Police('佐藤美和子',22,'woman','警察',2000) p2 = Police('高木涉',22,'man','警察',1500) s1 = Student('柯南',6,'man','侦探') s2 = Student('灰原哀',6,'woman','医药') p1.tell() # 能调用父类的方法 s1.tell() p2.doing() # 能调用各自类中的方法,不能调用其它类的方法(除了父类) s1.self_hobby()
Welcome to this cartoon,[佐藤美和子],now we have [1] member!
Welcome to this cartoon,[高木涉],now we have [2] member!
Welcome to this cartoon,[柯南],now we have [3] member!
Welcome to this cartoon,[灰原哀],now we have [4] member!
Hello,my name is [佐藤美和子]
Hello,my name is [柯南]
[高木涉] is a [警察].
Student [柯南] like [侦探].
三、类方法
class Animal(object): hobby = 'meat' def __init__(self,name): self.name = name @classmethod # 使它下面的方法只能访问类的变量,不能访问实例变量,例如self.name def talk(self): print("[%s] is talking..." %self.hobby) @staticmethod # 使它下面的既不能访问类的变量,也不能访问实例变量,即括号内没有参数 def walk(): print("[%s] is walking...") @property # 把一个方法变为一个属性,调用时不加后面的括号 def habit(self): print("[%s] habit is eating..." %self.name) a1 = Animal('sheep') a1.talk() a1.walk() a1.habit
[meat] is talking...
[%s] is walking...
[sheep] habit is eating...
四、类中的特殊方法
class A(object): ''' 这是注释 ''' def __init__(self,name): self.name = name def a(self): print('this is %s' %self.name) def __del__(self): # 析构方法,当程序结束后会自动执行这个方法,出发该方法中的功能,例如可以关闭一些东西 print("析构方法。。。") a1 = A('a') print(a1.__doc__) # 显示类中的注释 print(a1.__module__) # 表示当前的实例对象属于哪个模块,若不是属于导入的模块,则显示__main__ print(a1.__class__) # 表示当前的实例对象属于哪个模块 print(a1.__dict__) # 以字典的形式显示出对象中的成员变量
这是注释
__main__
<class '__main__.A'>
{'name': 'a'}
析构方法。。。
五、反射
import sys class WebServer(object): def __init__(self,host,port): self.host = host self.port = port def start(self): print("server is starting....") def stop(self): print("server is stopping....") def restart(self): self.stop() self.start() def test_run(name): print("%s is running...." %name) if __name__ == "__main__": print(sys.argv[1]) # 目的是给一个命令,可以执行命令相对应的方法功能,给的命令是字符串,怎么执行对应的功能,用反射 server = WebServer('localhost',2333) if hasattr(server,sys.argv[1]): # hasattr(实例,方法),判断实例中是否有这个方法,若有返回True func = getattr(server,sys.argv[1]) # 获得实例中该方法的内存地址 func() # 执行该方法,若该方法有参数,则直接在括号中加对应参数 setattr(server,'run',test_run) # setattr(实例,自己定义的方法名,函数名),为一个实例绑定一个不属于类的方法 server.run('zhu') # 可以当实例的方法来调用 delattr(WebServer,'stop') # 删除类中的方法,不能通过实例删除类中的方法,应为方法不存在实例中 delattr(server,'host') # 删除实例中的变量
六、异常处理
# 异常处理,程序报错时不停止,捕捉这个错误,并按照设计的的方式运行 dict_test = {'name':'zhu','sex':'mam'} list_test = [1,2,3] try: # try后面写出需要运行的可能出错的代码 print(list_test[3]) # try中的代码出现错误就会跳到except,不再往下执行,自动寻找对应的except错误代码 print(dict_test['age']) except KeyError as error_name: # except 错误类型 as 变量名,捕捉错误,并按照下面设计的程序运行 print("出现错误没有键:%s" %error_name) except IndexError as error_name: print("出现错误范围错误:%s" %error_name) except Exception as error_name: # 不知道错误类型时,这样使用捕捉错误 print("未知错误:%s" %error_name) else: # 没有错误时继续执行下面的代码 print("正常") finally: # 无论有没有错误,都执行下面的代码 print("执行代码") ''' 可以把错误写在一起,这样写的情况是几种错误的处理办法相同,可以放在一起 except (KeyError,IndexError) as error_name: print("出现错误:%s" %error_name) 可以抓住所有的错误,但具体哪个地方出错不能看到,不建议用 except Exception as error_name: print("出现错误:%s" %error_name) '''
# 自定义异常错误 class SqlExcepttion(Exception): # 定义异常的类 def __init__(self,msg): # 传入自定义异常的内容 self.message = msg def __str__(self): # 定义异常返回的格式 return self.message try: raise SqlExcepttion("数据库连接不上。。。") # 触发自己定义的异常 except SqlExcepttion as error_name: # 变量名的内容就是触发异常中括号中的内容 print("出现错误:%s" %error_name)