满足低调之心基础七(1)

一,静态方法,类方法,属性方法

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).

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值