1.在函数内部,如果 局部变量 和 全局变量 同名,使用的是 局部变量。
upChars = '零壹贰叁肆伍陆柒捌玖'
def getZh(num):
upChars = '零一二三四五六七八九'
print('对应的汉字是:' + upChars[num])
getZh(5)
在函数内部,如果 局部变量 和 全局变量同名,使用的是 局部变量,如果在函数内部要对全局变量进行重新赋值,不能直接这样:
upChars = '零壹贰叁肆伍陆柒捌玖'
def change():
upChars = '零一二三四五六七八九'
change()
print(upChars)
因为,解释器会认为函数内部 是重新定义了一个局部变量, 而不是把全局变量进行重新赋值。
应该这样做:
upChars = '零壹贰叁肆伍陆柒捌玖'
def change():
global upChars
upChars = '零一二三四五六七八九'
change()
print(upChars)
通过 global upChars
这行声明,表示 upChars 这个名字对应的是全局变量 upChars。
2.列表的内容可变,和列表不同,元组对象的内容是不可以变化的。
3.如果and 和 or 一起使用, 注意 是先计算 and 部分, 其结果 再和 or 一起计算。
4.如果not、 and 和 or 一起使用, 注意 是先计算 not , 再计算 and 部分, 最后再计算 or。
类和对象部分
1.类属性
是类的共同特征属性,类的静态方法要在方法定义 上面加上 @staticmethod
的修饰,而 类的 实例方法
不需要任何修饰。
class BenzCar:
brand = '奔驰' # 品牌属性
country = '德国' # 产地属性
@staticmethod
def pressHorn():
print('嘟嘟~~~~~~')
2.通常类的实例方法,都是要 访问类的实例属性的。 包括: 创建、修改、删除 类的实例属性。因为 实例方法 就是要操作 实例独有的属性,否则不操作任何实例属性的话,就应该定义为 类方法。比如 __init__
初始化方法,就是一个实例方法,它通常要创建一些实例属性。而 类的静态方法是不能访问实例属性的
。
class BenzCar:
brand = '奔驰'
country = '德国'
@staticmethod
def pressHorn():
print('嘟嘟~~~~~~')
# 初始化方法, 注意前后各有两个下划线
def __init__(self):
self.color = 'red' # 颜色
self.engineSN = '837873398' # 发动机编号
3.当 实例属性名称 和 静态属性 重复了
,通过类实例访问该属性,访问的是实例属性。通过类名访问该属性,访问的是类属性,比如:
class Car:
brand = '奔驰'
name = 'Car'
def __init__(self):
# 可以通过实例访问到类属性
print(self.brand)
# 定义实例属性和类属性重名
self.name = 'benz car'
c1 = Car()
print(f'通过实例名访问name:{c1.name}')
print(f'通过类名 访问name:{Car.name}')
4.在子类的初始化方法里面,如果有一部分的初始化代码和父类的初始化相同(通常都是这样),需要显式的 调用父类的初始化方法 __init__,
而且要传入相应的参数;
def __init__(self,color,engineSN,weight):
# 先调用父类的初始化方法
BenzCar.__init__(self,color,engineSN)
self.weight = weight
self.oilweight = 0
如果子类 没有
自己的初始化方法,实例化子类对象时,解释器会自动调用父类初始化方法,如下:
class Rect:
def __init__(self):
print('初始化 rect')
class Squre(Rect):
pass
s = Squre()
运行结果,会打印出 初始化 rect。
但是,如果子类 有自己
的初始化方法,实例化子类对象时,解释器就不会自动化调用父类的初始化方法,如下:
class Rect:
def __init__(self):
print('初始化 rect')
class Square(Rect):
def __init__(self):
print('初始化 square')
s = Squre()
运行结果只会打印 初始化 square
。
5.调用父类的方法,除了直接用父类的名字 BenzCar, 还可以使用 函数 super(),像这样:
def __init__(self,color,engineSN,weight):
# 同样是调用父类的初始化方法
super().__init__(color, engineSN)
self.weight = weight
self.oilweight = 0
这样使用的时候,方法参数中 不需要加上 self 参数。
使用super的好处之一就是:
- 子类中调用父类的方法,不需要 显式指定 父类的名字。 代码的可维护性更好。想象一下,如果BenzCar有很多子类,如果那一天BenzCar类改了名字,采用super这样的写法,就不需要修改子类的代码了。
- 在多重继承的情况,super能有效的保证继承链上的方法被正确调用到。
注意 super不仅仅可以调用父类的初始化方法,也可以调用父类的其他方法。
异常部分
1.如果我们想知道异常的详细信息,可以使用traceback模块,如下,
import traceback
try:
100/0
except :
print(traceback.format_exc())
在except下面缩进代码中,使用traceback模块里面的format_exc函数,可以显示异常的信息 和 异常产生处的函数调用栈的信息。
上面的代码会打印出导致异常的详细的函数调用栈的信息,如下:
Traceback (most recent call last):
File "xxxx/xxx.py", line 4, in <module>
100/0
ZeroDivisionError: division by zero