一,静态方法,类方法,属性方法
1,静态方法
咱们先任意写一个类:
class Dog(object):
def __init__(self, name, food):
self.NAME = name
self.FOOD = food
def eat(self):
print("The dog \033[31;1m%s\033[0m is eating \033[34;1m%s\033[0m" % (self.NAME, self.FOOD))
d = Dog("huahua", "meat")
d.eat()
G:\Python38\python.exe G:/Project1/self_taught/week_7/static_method.py
The dog huahua is eating meat
Process finished with exit code 0
这个已经很熟悉了,那么再看
class Dog(object):
def __init__(self, name, food):
self.NAME = name
self.FOOD = food
@staticmethod
def eat(self):
print("The dog \033[31;1m%s\033[0m is eating \033[34;1m%s\033[0m" % (self.NAME, self.FOOD))
d = Dog("huahua", "meat")
d.eat()
当我们加了个东西呢?运行发现报错了!
G:\Python38\python.exe G:/Project1/self_taught/week_7/static_method.py
Traceback (most recent call last):
File "G:/Project1/self_taught/week_7/static_method.py", line 31, in <module>
d.eat()
TypeError: eat() missing 1 required positional argument: 'self'
Process finished with exit code 1
说呀,eat()少一个参数"self",纳尼,是不是丈二和尚 —— 摸不着头脑
其实呢,加上了@staticmethod实际上eat()就和类没有什么关系了,只是类下面的一个函数而已。
那我就要获取eat()里的东西呢?
class Dog(object):
def __init__(self, name, food):
self.NAME = name
self.FOOD = food
@staticmethod
def eat():
print("The dog \033[31;1m%s\033[0m is eating \033[34;1m%s\033[0m" % ("huanhuan", "fish"))
d = Dog("huahua", "meat")
d.eat()
G:\Python38\python.exe G:/Project1/self_taught/week_7/static_method.py
The dog huanhuan is eating fish
Process finished with exit code 0
只需要借类名来调用下。
静态方法:只是名义上归类管,实际上已经访问不了类或实例中的任何属性。
2,类方法
在eat()上面加上@classmethod
class Dog(object):
def __init__(self, name, food):
self.NAME = name
self.FOOD = food
@classmethod
def eat(self):
print("The dog \033[31;1m%s\033[0m is eating \033[35;1m%s\033[0m" % (self.NAME, "fish"))
d = Dog("huahua", "meat")
d.eat()
发现运行后也报错了,报错的最后一句为:AttributeError: type object ‘Dog’ has no attribute ‘NAME’, 说Dog类没有"NAME"属性
再改改:
class Dog(object):
n = "Tom" # 类变量
def __init__(self, name, food):
self.NAME = name
self.FOOD = food
@classmethod
def eat(self):
print("The dog \033[31;1m%s\033[0m is eating \033[35;1m%s\033[0m" % (self.n, "fish"))
d = Dog("huahua", "meat")
d.eat()
G:\Python38\python.exe G:/Project1/self_taught/week_7/class_method.py
The dog Tom is eating fish
Process finished with exit code 0
这就是类方法:只能访问类变量,不能访问实例属性
3,属性方法
class Dog(object):
def __init__(self, name):
self.NAME = name
@property
def eat(self):
print("The dog \033[31;1m%s\033[0m is eating \033[34;1m%s\033[0m" % (self.NAME, "fish"))
d = Dog("huahua")
d.eat()
运行时会报错,报错内容为:TypeError: ‘NoneType’ object is not callable,说对象不可调用。
那么尝试改变一下
class Dog(object):
def __init__(self, name):
self.NAME = name
@property
def eat(self):
print("The dog \033[31;1m%s\033[0m is eating \033[34;1m%s\033[0m" % (self.NAME, "fish"))
d = Dog("huahua")
d.eat # ()去掉相当于调变量一样
G:\Python38\python.exe G:/Project1/self_taught/week_7/attribute_method.py
The dog huahua is eating fish
Process finished with exit code 0
so,属性方法:把一个方法变成一个静态属性
没有括号的话就没法传参数了,不过好像可以赋值,但是不能直接的赋值
class Dog(object):
def __init__(self, name):
self.NAME = name
@property
def eat(self):
print("The dog \033[31;1m%s\033[0m is eating \033[34;1m%s\033[0m" % (self.NAME, "fish"))
@eat.setter
def eat(self, sleep):
print("\033[36;1m%s\033[0m is sleeping..." % sleep)
d = Dog("huahua")
d.eat
d.eat = "pig"
G:\Python38\python.exe G:/Project1/self_taught/week_7/attribute_method.py
The dog huahua is eating fish
pig is sleeping...
Process finished with exit code 0
假如我想删除呢?
class Dog(object):
def __init__(self, name):
self.NAME = name
@property
def eat(self):
print("The dog \033[31;1m%s\033[0m is eating \033[34;1m%s\033[0m" % (self.NAME, "fish"))
@eat.setter
def eat(self, sleep):
print("\033[36;1m%s\033[0m is sleeping..." % sleep)
d = Dog("huahua")
d.eat
d.eat = "pig"
del d.eat
运行结果会报错,报错内容为:AttributeError: can’t delete attribute,说不能删除属性
假如我就想删掉呢?
class Dog(object):
def __init__(self, name):
self.NAME = name
@property
def eat(self):
print("The dog \033[31;1m%s\033[0m is eating \033[34;1m%s\033[0m" % (self.NAME, "fish"))
@eat.setter
def eat(self, sleep):
print("%s \033[36;1m%s\033[0m is sleeping..." % (self.NAME, sleep))
@eat.deleter
def eat(self):
del self.NAME
print("deleted")
d = Dog("huahua")
d.eat
d.eat = "pig"
del d.eat
G:\Python38\python.exe G:/Project1/self_taught/week_7/attribute_method.py
The dog huahua is eating fish
huahua pig is sleeping...
deleted
Process finished with exit code 0
然后我们再查看
class Dog(object):
def __init__(self, name):
self.NAME = name
@property
def eat(self):
print("The dog \033[31;1m%s\033[0m is eating \033[34;1m%s\033[0m" % (self.NAME, "fish"))
@eat.setter
def eat(self, sleep):
print("%s \033[36;1m%s\033[0m is sleeping..." % (self.NAME, sleep))
@eat.deleter
def eat(self):
del self.NAME
print("deleted")
d = Dog("huahua")
d.eat
d.eat = "pig"
del d.eat
d.eat
运行报错,报错内容为:AttributeError: ‘Dog’ object has no attribute ‘NAME’, 说Dog类没有"NAME"这个属性,说明删除成功!👏👏👏
上面就是把一个方法变成一个属性,去修改它,再删除它。
二,类的一些特殊方法
1,
# __call__是由对象后面加()触发的,即对象()或类()()
class Dog(object):
def __init__(self, name):
self.NAME = name
def shout(self, eat):
print("The dog %s is eating %s!" % (self.NAME, eat))
def __call__(self, *args, **kwargs):
print("hahaha", *args, **kwargs)
# d = Dog("huanhuan")
# d(1, 2, 2, 5, "pig", [123, 34], (7, 8), {"pig": "sleep"})
Dog("huanhuan")(1, 2, 2, 5, "pig", [123, 34], (7, 8), {"pig": "sleep"})
G:\Python38\python.exe G:/Project1/self_taught/week_7/others.py
hahaha 1 2 2 5 pig [123, 34] (7, 8) {'pig': 'sleep'}
Process finished with exit code 0
2,
class Dog(object):
def __init__(self, name):
self.NAME = name
def shout(self, eat):
print("The dog %s is eating %s!" % (self.NAME, eat))
print(Dog.__dict__) # 打印类里的所有属性,但是不包括实例属性
d =Dog("huanhuan")
print(d.__dict__) # 打印所有的实例属性,不包括类属性
G:\Python38\python.exe G:/Project1/self_taught/week_7/others.py
{'__module__': '__main__', '__init__': <function Dog.__init__ at 0x00000141E0CE2EE0>, 'shout': <function Dog.shout at 0x00000141E0CE2F70>, '__dict__': <attribute '__dict__' of 'Dog' objects>, '__weakref__': <attribute '__weakref__' of 'Dog' objects>, '__doc__': None}
{'NAME': 'huanhuan'}
Process finished with exit code 0
3,
class Dog(object):
def __init__(self, name):
self.NAME = name
def shout(self, eat):
print("The dog %s is eating %s!" % (self.NAME, eat))
def __str__(self): # 默认输出该方法的返回值
return "obj:%s" % self.NAME
d =Dog("huanhuan")
print(d)
G:\Python38\python.exe G:/Project1/self_taught/week_7/others.py
obj:huanhuan
Process finished with exit code 0
4,一种特殊的方法创建类
def talk(self):
print("The pig %s like eat %s everyday!" % (self.NAME, self.EAT))
def __init__(self, name, eat):
self.NAME = name
self.EAT = eat
Animal = type("Animal", (object,), {"talk": talk,
"__init__": __init__})
f = Animal("huahua", "vegetable")
f.talk()
三,反射
一共有四个方法:
hasattr(), getattr(), setattr(), delattr(),它们分别干啥的呢?咱们在代码中心领神会
1,
class Dog(object):
def __init__(self, name):
self.NAME = name
def eat(self, food):
print("%s is eating %s..." % (self.NAME, food))
d = Dog("huanhuan")
choice = input(">>>>:").strip()
print(hasattr(d, choice)) # 判断一个对象d里是否有对应的choice字符串方法
G:\Python38\python.exe G:/Project1/self_taught/week_7/reflex.py
>>>>:eat
True
Process finished with exit code 0
G:\Python38\python.exe G:/Project1/self_taught/week_7/reflex.py
>>>>:sleep
False
Process finished with exit code 0
2,
class Dog(object):
def __init__(self, name):
self.NAME = name
def eat(self):
print("%s is eating %s..." % (self.NAME, "vegetable"))
d = Dog("huanhuan")
choice = input(">>>>:").strip()
print(hasattr(d, choice)) # 判断一个对象d里是否有对应的choice字符串方法
print(getattr(d, choice)) # 根据字符串去获取d对象里对应方法的内存地址
getattr(d, choice)() # 加上()就可以调用
G:\Python38\python.exe G:/Project1/self_taught/week_7/reflex.py
>>>>:eat
True
<bound method Dog.eat of <__main__.Dog object at 0x000002453E1F64C0>>
huanhuan is eating vegetable...
Process finished with exit code 0
3,
def bulk(self):
print("%s is yelling..." % self.NAME)
class Dog(object):
def __init__(self, name):
self.NAME = name
def eat(self):
print("%s is eating %s..." % (self.NAME, "vegetable"))
d = Dog("huanhuan")
choice = input(">>>>:").strip()
if hasattr(d, choice):
func = getattr(d, choice)
func("meat")
else:
setattr(d, choice, bulk) # 创建一个新方法
d.bulk(d)
G:\Python38\python.exe G:/Project1/self_taught/week_7/reflex.py
>>>>:bulk
huanhuan is yelling...
Process finished with exit code 0
4,
class Dog(object):
def __init__(self, name):
self.NAME = name
def eat(self):
print("%s is eating %s..." % (self.NAME, "vegetable"))
d = Dog("huanhuan")
choice = input(">>>>:").strip()
if hasattr(d, choice):
delattr(d, choice) # 删除
print(d.NAME)
G:\Python38\python.exe G:/Project1/self_taught/week_7/reflex.py
>>>>:NAME
Traceback (most recent call last):
File "G:/Project1/self_taught/week_7/reflex.py", line 34, in <module>
print(d.NAME)
AttributeError: 'Dog' object has no attribute 'NAME'
Process finished with exit code 1
报错说明删除成功!
四,异常处理
异常处理的作用:虽然程序出错了,但是我不想让用户看到这个错误,即我提前知道程序可能会出错,所以提前做一些预处理,防止整个程序的崩溃而无法继续往下运行。
先看简单的例子:
name =["hpl", "jack"]
try:
name[3]
except IndexError as e:
print("List operation error:", e) # e就是错误的详细信息
G:\Python38\python.exe G:/Project1/self_taught/week_7/abnormal_handle.py
List operation error: list index out of range
Process finished with exit code 0
dict = {}
try:
dict["name"]
except KeyError as e:
print("Didn't find this key:", e)
G:\Python38\python.exe G:/Project1/self_taught/week_7/abnormal_handle.py
Didn't find this key: 'name'
Process finished with exit code 0
再看同时出现多个错误:
name =["hpl", "jack"]
dict = {}
try:
open("new.txt")
except KeyError as e:
print("Didn't find this key:", e)
except IndexError as e:
print("List operation error:", e) # e就是错误的详细信息
except Exception as e: # 抓所有位置的错误
print("unknown error:", e)
G:\Python38\python.exe G:/Project1/self_taught/week_7/abnormal_handle.py
unknown error: [Errno 2] No such file or directory: 'new.txt'
Process finished with exit code 0
keep on:
try:
a = 1
print(a)
except KeyError as e:
print("Didn't find this key:", e)
except IndexError as e:
print("List operation error:", e) # e就是错误的详细信息
except Exception as e: # 抓所有位置的错误
print("unknown error:", e)
else: # 没有错误是走这里
print("The program runs normally!!!")
finally: # 不管有没有错都执行
print("No matter what's wrong, do it!")
G:\Python38\python.exe G:/Project1/self_taught/week_7/abnormal_handle.py
1
The program runs normally!!!
No matter what's wrong, do it!
Process finished with exit code 0
真的所有的错误都能抓住吗?
look a example
name =["hpl", "jack"]
try:
name[3] # 这里我特意写了个缩进错误,看Exception是否能抓住
except KeyError as e:
print("Didn't find this key:", e)
except IndexError as e:
print("List operation error:", e) # e就是错误的详细信息
except Exception as e: # 抓所有位置的错误
print("unknown error:", e)
G:\Python38\python.exe G:/Project1/self_taught/week_7/abnormal_handle.py
File "G:/Project1/self_taught/week_7/abnormal_handle.py", line 8
name[3] # 这里我特意写了个缩进错误,看Exception是否能抓住
^
IndentationError: expected an indented block
Process finished with exit code 1
运行结果报错了,错误也被指出来的,缩进错误,看来并不是所有的错误都能被抓住,这个条件是要建立在代码能正常编译的基础上。
自定义异常:
class HplException(Exception):
def __init__(self, msg):
self.message = msg
try:
raise HplException("The database cannot be connected!") # raise可以引发异常,括号里面可以写任何内容
except HplException as e:
print(e)
G:\Python38\python.exe G:/Project1/self_taught/week_7/abnormal_handle.py
The database cannot be connected!
Process finished with exit code 0
链接: 满足低调之心基础七(2).