开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 7 天,点击查看活动详情
1. 模块、包、库的定义
模块(module):.py文件。
包(package):一组协同工作的python模块。文件夹[文件夹[文件夹[.py文件]]]
库(library):库是公开可调用的包。
2. import 和 from import的区别
import
在开始使用一个模块中的函数或者类之前,必须用import module1[module2...[modulen]]语句导入该模块。但是由于import只能导入包、子包、模块,不能导入模块中的函数、类、变量等。
因此如果我们想用某个模块中的函数或者类,必须在函数或者类前使用modulen.的前缀才能使用。
例如:
#使用random模块中的randint()函数生成1-100的随机数
import random
random_integer = random.randint(1, 100)
from import
from import可以导入模块、子包、包、类、函数、变量,from module1[module2...[modulen]] import modulen+1,function,class,variant 。使用这种方法如果导入了函数或类则不需要使用modulen.的前缀,相当于直接把函数或类拿进来了这个模块里。这个方法虽然方便但可读性不好。
例如:
#使用random模块中的randint()函数生成1-100的随机数
from random import randint
random_integer = randint(1, 100)
3. 类
定义一个类并创建实例
通常我们是这样认为的,创建一个类的实例才可以通过实例调用类内的方法和属性。
#定义Circle类
class Circle():
pass
#创建实例
circle1= Circle()
circle2= Circle()
类属性和实例属性
类属性从属于一个类,它不属于任何的实例。不需要创建实例,就可以读取和修改这个值。
class Circle():
pi=3.14
#你不需要创建一个实例,就能访问类属性
print(Circle.pi) #3.14
Circle.pi=3.14159
print(Circle.pi)#3.14159
#你也可以创建一个实例去访问类属性
circle1=Circle()
print(circle1.pi) #3.14159
#你若通过实例去修改实际上是给circle1创建了一个与类属性同名的实例属性。
circle1.pi=3.1
print(Circle.pi)#3.14159 跟随类的属性并没有改变
print(circle1.pi)#3.1
那么实例属性,顾名思义是从属于实例的。
#添加实例属性方法一
class Circle():
pi=3.14
circle1=Circle()
#你完全可以通过实例. 的方式去添加实例属性
circle1.r=3
print(circle1.r)
但是我们通常会认为方法一这样添加属性给每个实例,未免也太麻烦了。既然类意为大家是一个模子里刻出来的,那么创建实例的时候一起添加都有的属性好啦。
定义类的时候还没有实例存在,创建实例时circle1=Circle(3),会自动调用 _init_(self,r)传入实例和参数,此时self就被激活,self就代表类的实例cilcle1,实例属性r被赋予了值。
#添加实例属性方法二
class Circle():
pi=3.14
def __init__(self,r):
self.r=r
circle1=Circle(3)
print(circle1.r)
类的实例方法
self的意义是什么,我理解为:当创建一个实例时,
self=被创建的实例,例如这里的self=circle1。实例通过 self 去绑定属于自己的实例属性和实例方法,这样各个实例之间不会冲突,各用各自的属性和方法。就比如:一创建实例,会自动调用_init_方法,通过self,实例对象circle1绑定自己的init方法,又添加了自己的属性r:
self.r=r → cilcle1.r=r
通过实例访问的类内方法叫做实例方法,如get_area(self,p)。_init_是特殊的实例方法。
实例方法与类外的函数不同在于,第一个参数必须设置为self,实例方法互相调用要用self.,实例方法调用实例属性要用self.。很容易理解,如我们上面所说的,因为实例属性和实例方法都要跟随着实例的。
class Circle():
pi=3.14
def __init__(self,r):
self.r=r
def get_area(self,p):
self.p=p
area=self.pi*self.r*self.r
print(area)
circle1=Circle(3)
circle1.get_area(4)
class Circle():
pi=3.14
def __init__(self,r):
self.r=r
def sum(self):
s=2*self.pi*self.r
return s
def get_round(self):
#类中函数相互调用要加self例如:self.sum(),
#这是因为如果调用get_round要把实例传进去激活self。
round=self.sum()
return round
circle1=Circle(3)
round=circle1.get_round()
print(round)
记录:3.7早晨刷题的时候纠结了一下:到底什么时候应该加上self,什么时候不加self?为什么class TreeNode的 __init__中的变量都加self,而Solution的maxDepth中的depth、root不需要self。
换个思维应该认为self是全局变量,如果变量前面加了self,那么在任何实例方法(非staticmethod和calssmethod)就都可以访问这个变量了,如果没有加self,只有在当前函数内部才能访问这个变量。
在class TreeNode中其他方法也会调用val、left、right。而Solution则不需要。
#求深度
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
#maxDepth方法是我写的
def maxDepth(self, root: Optional[TreeNode]) -> int:
depth=0
if root:
depth=max(self.maxDepth(root.left),self.maxDepth(root.right))+1
return depth
我可以像上面那样在__init__中传入参数: def __init__(self, val=0, left=None, right=None)然后用self绑定。也可以像下面这样不需要传参,凡是加上了self,就代表着与当前的实例是绑定的。
class Tree:
def __int__(self):
self.val=0
self.left=None
self.right=None
tree1=Tree()
tree1.val=1
tree1.left=2
tree1.right=3
print(str(tree1.val)+"→"+str(tree1.left)+"→"+str(tree1.right)) #1→2→3