Python类、实例、方法、继承与模块引用
原创:丶无殇 2023-02-16
包含:属性 attribute、方法 method
一个人的身高、体重和年龄,这些都是属性,而吃饭、说话和洗澡都是方法
类
和实例对象
是有区别的,类是抽象,是模板,而实例
则是根据类创建的对象
比如类:动物,只是一个抽象,并没有动物的详细信息,而猫、狗等,则是具体的动物,是类的对象。
在class外部定义的可执行函数叫做function,类内部的函数叫做方法method
类名开头大写,无括号,在Python3中Person
、Person()
、Person(object)
,效果一样,但在Python2中需要写成Person(object)
class Person: # Person/Person()/Person(object)
换行缩进后定义属性和方法,属性为变量;方法的定义和函数一样(def开头)
class Person:
# 属性
name='zhangsan'
age=29
height=1.82
# 方法
def greet(self):# 打招呼方法
print(f"你好,我叫{self.name},我今年{self.age}岁")
# 创建实例
p1=Person()
# 调用方法
p1.greet()
输出:
你好,我叫zhangsan,我今年29岁
类的定义是一个具体实例(instance)的设计蓝图,在创建实例的时候,只需要调用类名()
就可以了
p1.greet()
是方法调用的示范,在实例后面加上.
可以调用方法
和属性
,如p1.name
类名使用:大骆驼命名法(UpperCamelCase)
实例和模块名:蛇形命名法(snake_case)
特殊参数self
会指向实例本身
self.name
—>当前被创建实例的name
属性
%s
/%d
/%f
print时候用格式化符号%s
/%d
/%f
占位,字符串后面紧接%()
,括号中为对应的参数名称
class Person:
# 属性
name='zhangsan'
age=29
height=1.82
# 方法
def greet(self):# 打招呼方法
print("你好,我叫%s,我今年%d岁,身高是%.2f米"%(self.name,self.age,self.height))
# 创建实例
p1=Person()
# 调用方法
p1.greet()
输出:
你好,我叫zhangsan,我今年29岁,身高是1.82米
f'{
表达式:
格式化}'
[Python3.6新增]在输出内容的前面加上f
,内容中需要变量的地方使用{}
即可
参数为浮点数
时候可以使用:.2f
来设置浮点数的格式
class Person:
# 属性
name='zhangsan'
age=29
height=1.823
# 方法
def greet(self):# 打招呼方法
print(f"你好,我叫{self.name},我今年{self.age}岁,身高是{self.height:.2f}米")
# 创建实例
p1=Person()
# 调用方法
p1.greet()
输出:
你好,我叫zhangsan,我今年29岁,身高是1.82米
.format
语法使用{}
占位,字符串后接.format()
,括号中为对应的参数名称
参数为浮点数
时候使用{:.2f}
设置浮点数的格式
class Person:
# 属性
name='zhangsan'
age=29
height=1.823
# 方法
def greet(self):# 打招呼方法
print("你好,我叫{},我今年{}岁,身高是{:.2f}米".format(self.name,self.age,self.height))
# 创建实例
p1=Person()
# 调用方法
p1.greet()
输出:
你好,我叫zhangsan,我今年29岁,身高是1.82米
__init__
是 Python 中的特殊方法(special method),它用于初始化对象,在实例别创建后最先调用的函数,第一参数永远是self
class Person:
# 初始化方法
def __init__(self):
self.name = '张三'
# 自定义方法
def greet(self):
print('你好,我是'+self.name)
p1=Person()
p1.greet()
输出:
你好,我是张三
在初始化方法中的参数,为必填参数
,创建实例的时候不填写会报错
class Person:
# 初始化方法
def __init__(self,init_name):
self.name = init_name
# 自定义方法
def greet(self):
print('你好,我是'+self.name)
p1=Person('李四')
p1.greet()
输出:
你好,我是李四
目前的方法只能传递固定个数的参数,如果想要传递任意参数,如:自定义求平均数的average()
方法,使用时候可以是average(22,33,45)
,也可以是average(2,6,8,5,6,9,10)
详情见:可变参数
创建好Person
类后,设置类属性count
,每创建一个实例count+1
class Person:
# 类属性
count=0
# 初始化方法
def __init__(self):
Person.count+=1
# 实例化对象
p1=Person()
p2=Person()
p3=Person()
print(Person.count)
输出:
3
在创建好实例p1
后,修改它的属性
# 修改实例属性
p1.age=21
print(p1.age)
# 删除实例属性
del Person.height
print(Person.height)
# 删除实例
del p1
print(p1)
删除只能通过删除类属性实现,不能直接删除
实例属性
删除方法除了del
还可以使用delattr()
函数
delattr(ClassName,Attribute)
相等于 del ClassName.Attribute
输出:
# 删除属性,报错内容
Traceback (most recent call last):
File "" , line 1, in <module>
AttributeError: 'Person' object has no attribute 'height'
# 表示已经删除了'Person.height'属性
# 删除实例,报错内容
Traceback (most recent call last):
File "" , line 1, in <module>
NameError: name 'p1' is not defined
#表示已经删除了'p1'实例对象
类属性优先级高于
实例属性,无法通过实例修改类属性,修改的只是对应的实例属性
class Animal:
localtion = 'Asia'
def __init__(self,localtion):
self.localtion = localtion
dog = Animal('GuangDong')
cat = Animal('Africa')
print(dog.localtion) # ==> GuangDong
print(cat.localtion) # ==> Africa
cat.localtion='ChongQing'
print(cat.localtion) # ==> ChongQing
print(Animal.localtion) # ==> Asia
输出:
GuangDong
Africa
ChongQing
Asia
单下划线开头的属性,只有类实例和子类实例可以访问,不能通过from module import *
导入,保护属性,不建议调用访问,不会被代码提示工具显示,但是可以直接访问
双下划线开头的属性/方法,只有类对象自己能访问,子类对象无法访问
#-*- coding:utf-8 -*-
class A(object):
def __init__(self):# 系统定义方法
self.string='A string' # 公有属性
self._string='A _string' # 保护属性
self.__string='A __string' # 私有属性
def fun(self):
return self.string + ' fun-A'
def _fun(self):
return self._string+' _fun-A'
def __fun(self):# 私有方法
return self.__string+' __fun-A'
def for__fun(self):# 内部调用私有方法
return self.__fun()
class B(A):# A的子类
def __init__(self):# 系统定义方法
self.string = 'B string'
a=A()
print(a.string)
print(a._string)
# print(a.__string)# 不可访问
print(a.fun())
print(a._fun())
# print(a.__fun())# 不可访问
print(a.for__fun())
b=B()
print(b.fun())
print(b.fun().__len__())# 系统定义函数
输出:
A string
A _string
A string fun-A
A _string _fun-A
A __string __fun-A
B string fun-A
14
通过实例方法
调用私有属性
,可以实现访问和修改等操作
在外部调用实例方法时,是不需要显式传递self参数的
class Animal:
# 初始化方法
def __init__(self,name,age):
self.__name=name
self.__age=age
# 获取信息
def get_info(self):
return 'name={},age={}'.format(self.__name,self.__age)
# 修改信息
def set_info(self,name,age):
self.__name=name
self.__age=age
# 实例化对象
dog=Animal('wc',2)
print(dog.get_info())
# 调用实例方法修改私有属性
dog.set_info('nidie',3)
print(dog.get_info())
输出:
name=wc,age=2
name=nidie,age=3
通过实例强制访问私有属性:实例名._类名__属性名
class Animal:
# 初始化方法
def __init__(self,name,age):
self.__name=name
self.__age=age
# 实例化对象
dog=Animal('wangwang',2)
# 强制访问私有属性
print(dog._Animal__name)
print(dog._Animal__age)
输出:
wangwang
2
操作实例对象的属性可以使用实例方法
,如果需要操作类的属性,就需要使用类方法
类方法需要使用装饰器@classmethod
与实例方法不同的是:
- 类方法需要使用@classmethod来标记为类方法,否则定义的还是实例方法
- 类方法的第一个参数将传入类本身,通常将参数名命名为 cls,上面的 cls.__localtion 实际上相当于Animal.__localtion
- 类方法无法获得任何实例属性,只能获得类的引用
在类Animal
中,创建实例dog,cat
,可以通过该实例
调用的方法,如dog.get_info
等
# -*- coding=utf-8 -*-
class Animal:
# 私有属性
__count=0
# 初始化方法
def __init__(self,name,age):
self.name=name
self.age=age
Animal.__count+=1
# 实例方法
def get_info(self):
return '我是{},今年{}岁了。总计数:{}个'.format(self.name,self.age,self.__count)
# 类方法
@classmethod
def get_cnt(cls):
return cls.__count
dog=Animal('汪汪',2)
cat=Animal('喵喵',3)
print(dog.get_info())
print(cat.get_info())
输出:
我是汪汪,今年2岁了。总计数:2个
我是喵喵,今年3岁了。总计数:2个
类方法不能直接操作实例属性,必须通过类实例才能操作。
类方法推荐
使用类名直接调用
,当然也可以使用实例对象调用
(不推荐)。
如Animal.get_cnt
可以调用,使用dog.get_cnt
也可以调用,但是不推荐这样使用
dog=Animal('汪汪',2)
cat=Animal('喵喵',3)
print(dog.get_cnt())
print(Animal.get_cnt())
输出:
2
2
当已经创建了一个类Person
后,还可以再细分为其他类,这些类和Person
类相似,比如添加几个属性,修改几个方法
此时,不需要重新新建一个类,可以从原来的类中派生一个新的类,原来的称为父类
或者基类/超类
,派生出的称为子类
,子类继承了父类的所有数据和方法
# 父类
class Animal:
def __init__(self,name):
self.name=name
def greet(self):
print(f'我是{self.name}')
# 子类继承父类
class Dog(Animal):
def greet(self):
print(f'汪汪,我是{self.name}')
Dog 类是从 Animal 类继承而来的,Dog 类自动获得了 Animal 类的所有数据和方法,而且还可以对从父类继承来的方法进行修改,调用的方式是一样的
animal = Animal('animal')
animal.greet()
dog = Dog('dog')
dog.greet()
输出:
我是animal
汪汪,我是dog
给子类Dog
添加一个run
的方法
# 子类
class Dog(Animal):
def greet(self):
return (f'汪汪,我是{self.name}')
# 跑的方法
def run(self):
return ('撒丫子')
dog=Dog('dog')
print(dog.greet()+',我在'+dog.run())
输出:
汪汪,我是dog,我在撒丫子
super()
函数是用于调用父类的一个方法
是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是如果使用多继承,会涉及到MRO【方法解析顺序(Method Resolution Order)】、重复调用(钻石继承)等种种问题
super(class[,self]).method(param1...)
super(class[,self]).__init__(param1...)
此处的class
为当前的子类名
,如class Person
中,子类class Student(Person)
,super
语句为super(Student,self).__init__(name,age)...
super().method(param1...)
super().__init__(param1...)
继承父类的属性和方法,使用spuer
方法,新增的属性单独添加
# 父类
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def greet(self):
print(f'我是{self.name},我{self.age}了')
# 子类
class Teacher(Person):
def __init__(self,name,age,score):
# 继承父类的属性,使用super继承name,age
super(Teacher,self).__init__(name,age) # super(Teacher,self).__init__(name,age)
# 新增的属性单独添加
self.score=score
def greet(self):
# 继承父类的方法,输出内容为父类的print内容
super(Teacher,self).greet() # super(Teacher,self).greet()
print(f'我是{self.name},我{self.age}了,综合评分{self.score}')
t=Teacher('张三',29,87.5)
t.greet()
输出:
我是张三,我29了
我是张三,我29了,综合评分87.5
#!/usr/bin/python
# -*- coding: UTF-8 -*-
class Parent(object):
def __init__(self):
self.parent = '我是父类'
print ('Parent')
def info(self,message):
print ("%s 来自父类" % message)
class Child(Parent):
def __init__(self):
# super(Child,self)首先找到Child的父类Parent,然后把类Child的对象转换为类Parent的对象
super(Child,self).__init__()
print ('子类')
def info(self,message):
super(Child, self).info(message)
print ('子类的 info 方法')
print (self.parent)
# 主函数
if __name__ == '__main__':
child = Child()
child.info('Hello World')
输出:
Parent
子类
Hello World 来自父类
子类的 info 方法
我是父类
通过isinstance()
函数可以判断一个变量的类型
isinstance(type,class)# 判断type是不是class类型
现有父类Person(name,gender)
,子类Student(name,gender,score)
、Teacher(name,gender,course)
class Person(object):
def __init__(self, name, gender):
self.name = name
self.gender = gender
class Student(Person):
def __init__(self, name, gender, score):
super(Student, self).__init__(name, gender)
self.score = score
class Teacher(Person):
def __init__(self, name, gender, course):
super(Teacher, self).__init__(name, gender)
self.course = course
p = Person('Tim', 'Male')
s = Student('Bob', 'Male', 88)
t = Teacher('Alice', 'Female', 'English')
判断p,s,t
这几个变量的时候可以使用isinstance()
判断类型
isinstance(p,Person) # ==> True
isinstance(p,Student) # ==> False
isinstance(p,Teacher) # ==> False
这说明在继承链上,一个父类的实例不能是子类类型,因为子类比父类多了一些属性和方法
isinstance(s,Person) # ==> True
isinstance(s,Student) # ==> True
isinstance(s,Teacher) # ==> False
因为Student
继承自Person
,所以s
也是Person
类型
它是指对不同类型的参数进行相同的操作,根据对象类型不同做出不同的行为,继承拿到父类的数据和方法,子类可以重新父类的方法,可以自己添加新的方法,有了继承才有多态,实现为不同数据提供一个统一的接口
class Person(object):
def __init__(self, name, gender):
self.name = name
self.gender = gender
def who(self):
return 'I am a Person, my name is %s' % self.name
class Student(Person):
def __init__(self, name, gender, score):
super(Student, self).__init__(name, gender)
self.score = score
def who(self):
return 'I am a Student, my name is %s' % self.name
class Teacher(Person):
def __init__(self, name, gender, course):
super(Teacher, self).__init__(name, gender)
self.course = course
def who(self):
return 'I am a Teacher, my name is %s' % self.name
p = Person('Tim', 'Male')
s = Student('Bob', 'Male', 88)
t = Teacher('Alice', 'Female', 'English')
print(p.who())
print(s.who())
print(t.who())
输出:
I am a Person, my name is Tim
I am a Student, my name is Bob
I am a Teacher, my name is Alice
这种行为别成为多态,一般调用的时候先从子类自身查找方法,如果自身没有,再按照继承链向上找
多种继承主要在出现组合情况的时候使用,如果没有多重继承,那么使用组合情况可能需要更多的子类
例如python的网络服务器有:TCPServer
、UDPServer
、UnixStreamServer
、UnixDatagramServer
服务器运行模式有:多线程ThreadingMixin
和多进程ForkingMixin
要创建多线程
的TCPServer
class MyServer(TCPServer,ThreadingMixin)
要创建多进程
的UPDServer
class MyServer(UPDServer,ForkingMixin)
已知类Student、Teacher继承Person类,技能类BasketballMixin、FootballMixin继承SkillMixin类,请通过多重继承,分别定义“会打篮球的学生”和“会踢足球的老师”
# -*- coding=utf-8 -*-
# 人员
class Person(object):
def __init__(self):
print("Person")
class Student(Person):
def __init__(self):
super(Student,self).__init__()
print("Student")
class Teacher(Person):
def __init__(self):
super(Teacher,self).__init__()
print("Teacher")
# 技能
class SkillMixin(object):
def __init__(self):
print("SkillMixin")
class BasketballMixin(SkillMixin):
def __init__(self):
super(BasketballMixin,self).__init__()
print("BasketballMixin")
class FootballMixin(SkillMixin):
def __init__(self):
super(FootballMixin,self).__init__()
print("FootballMixin")
# 会打篮球的学生
class BasketballStudent(BasketballMixin,Student):
def __init__(self):
super(BasketballStudent,self).__init__()
print('会打篮球的学生')
# 会踢足球的老师
class FootballTeacher(FootballMixin,Teacher):
def __init__(self):
super(FootballTeacher,self).__init__()
print('会踢足球的老师')
s=BasketballStudent()
t=FootballTeacher()
输出:
SkillMixin
BasketballMixin
会打篮球的学生
SkillMixin
FootballMixin
会踢足球的老师
前文中,可以通过isinstance()
方法来判断是否是某个类型,现在需要获取更多的信息
通过type()
方法可以获取变量的类型
class Person(object):
def __init__(self, name, gender):
self.name = name
self.gender = gender
class Student(Person):
def __init__(self, name, gender, score):
super(Student, self).__init__(name, gender)
self.score = score
p = Person('Alice', 'Female')
s = Student('Bob', 'Male', 100)
type(p) # ==>
type(s) # ==>
输出:
<class '__main__.Person'>
<class '__main__.Student'>
通过dir()
方法可以获取变量的所有属性
dir(p)
输出:
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'gender', 'name']
dir()
返回的属性是字符串列表
,其中__xxx__
为特殊属性和方法,可以直接访问
如果其中存在私有属性
,如:初始化属性中的gender
改为self.__gender=gender
,则输出:
['_Person__gender', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__',
'__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'name']
dir()
返回的属性是字符串列表
,如果已知一个属性名称,要获取或者设置对象的属性,就需要用 getattr()
和 setattr()
函数
如上例中的:
p = Person('Alice', 'Female')
s = Student('Bob', 'Male', 100)
获取p
的name
属性
getattr(p,'name') # ==> 'Alice'
如果有私有属性,需要强制访问,方式为_类名__属性名
(详情见:强制访问私有属性)
getattr(p,'_Person__gender') # ==> 'Female'
如果获取的属性不存在,则会报错
getattr(p,'age') # ==> AttributeError: 'Person' object has no attribute 'age'
如果获取的属性不存在,指定默认返回值
getattr(p,'age',20) # ==> 'Female'
设置属性值
setattr(p,'name','Mike') # 'Alice' ==> 'Mike'
可以用setattr()
方法来设置属性值,可变参数,可以用来添加任意关键字参数,以键值对
的方式设置值
class Person(object):
def __init__(self, name, gender, **agrv):
self.name = name
self.gender = gender
for k,v in agrv.items():
setattr(self,k,v)
p = Person('Bob', 'Male', age=18, course='Python')
print(p.age)
print(p.course)
输出:
18
Python
如果不使用setattr()
方式来添加参数,可以使用for循环遍历
,例如设计一个求平均数的函数
def average(*agrv):
sum = 0
if len(agrv) == 0:
print(sum)
for i in agrv:
sum += i
avg = sum / len(agrv)
print(avg)
average(1,5,6,24)
输出:
9.0
通常变量可以通过str()
函数转换为字符串类型输出,但是自定义的类无法转换成字符串
class Person:
# 初始化方法
def __init__(self):
self.name = '张三'
# 自定义方法
def greet(self):
print('你好,我是'+self.name)
p1=Person()
p1.greet()
str(p1)
输出:
你好,我是张三
'<__main__.Person object at 0x00000257907AD760>'
输出发现str()
返回的是这个实例的地址,这是因为使用的是对象的内建方法__str__
返回的
如果自定义的类也实现__str__()
方法,便可以转换为字符串输出
class Person:
# 初始化方法
def __init__(self):
self.name = '张三'
# 自定义方法
def greet(self):
print('你好,我是'+self.name)
def __str__(self):
return '你好,我是'+self.name # return str(self.name)
p1=Person()
p1.greet()
str(p1)
输出:
你好,我是张三
'你好,我是张三'
此时发现,如果只输入p1
,显示的仍然是地址
<__main__.Person object at 0x00000257907A4E50>
上述情况是因为Python定义了__str__()
和__repr__()
两种方法,__str__()
显示给用户,而__repr__()
显示给开发人员,当使用str()
时候,实际调用的是__str__()
方法,而直接输入变量,调用的是__repr__()
方法,所以需要再实现__repr__()
方法
class Person:
# 初始化方法
def __init__(self):
self.name = '张三'
# 自定义方法
def greet(self):
print('你好,我是'+self.name)
def __str__(self):
return '你好,我是'+self.name
def __repr__(self):
return '你好,我是'+self.name
p1=Person()
p1.greet()
str(p1)
输出:
你好,我是张三
'你好,我是张三'
你好,我是张三
对于列表List和元组Tuple,都可以使用内建方法len()来获取元素个数,如果需要达到这个效果,就需要实现__len__()
方法
例如有个班级Class类,初始化把学生列表传进去,通过len()函数可以返回学生个数
class Class:
def __init__(self,students):
self.students=students
def __len__(self):
return len(self.students)
stu=['Mike','James','Alice']
cls=Class(stu)
print(f'此班级有 {len(cls)} 名学生')
输出:
此班级有 3 名学生
实现一个斐波那契数列:0,1,1,2,3,5,8…,创建一个Fib
类,Fib(10)
表示数列前十个元素,print(Fib(10))
可以打印输出,len(Fib(10))
可以返回数列个数10
class Fib(object):
def __init__(self,num):
self.res=[]
self.num=num
a,b=0,1
for i in range(num):
self.res.append(a)
a,b=b,a+b
def __str__(self):
return str(self.res)
def __len__(self):
return len(self.res)
f=Fib(10)
print(f)
print(str(f))
print(len(f))
输出:
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
10
用来限制可添加的属性,如此时有一个Student
类,包含name,gender,score
这几个属性
class Student:
def __init__(self,name,gender,score):
self.name = name
self.gender = gender
self.score = score
类中的参数都可以动态的添加,如此时再添加一个age
属性
s=Student('Mike','Male',87)
s.age=25 # 动态添加属性age
如果不做限制,会有很多属性,不便于后期管理,所以需要使用__slots__()
方法来限制添加的属性
class Student:
__slots__ = ('name', 'gender', 'score','total')
def __init__(self,name,gender,score):
self.name = name
self.gender = gender
self.score = score
此时执行动态添加属性age
的语句,会报错,如果添加total
则不会报错
Traceback (most recent call last):
File "" , line 1, in <module>
AttributeError: 'Student' object has no attribute 'age'
假设Person类通过__slots__
定义了name
和gender
,请在派生类Student
中通过__slots__
继续添加score
的定义,使Student
类可以实现name
、gender
和score
3个属性。
class Person(object):
__slots__=['name','gender']
def __init__(self,name,gender):
self.name=name
self.gender=gender
class Student(Person):
__slots__=['score']
def __init__(self,name,gender,score):
super(Student,self).__init__(name,gender)
self.score=score
s=Student('Alice','Female',96)
s.name='Bob'
s.score=87
print(s.score)
Python中,函数是一个对象,可以将一个函数赋值给一个变量,且不改变函数的功能
>>> f=abs
>>> f
<built-in function abs>
>>> f.__name__
'abs'
>>> f(-123)
123
此时,f
被称为可调用的对象
,其实所有的函数都是可调用对象
如果把一个类实例也变成一个可调用对象(函数),需要实现一个__call__()
方法
class Person:
def __init__(self,name,age):
self.name = name
self.age = age
def __call__(self,friend):
print('My name is {}.'.format(self.name))
print('My friend is {}.'.format(friend))
p=Person('Bob',25)
p('Mike') # ==> 用函数的方式调用Person类的实例p
输出:
My name is Bob.
My friend is Mike.
对前面的斐波那契数列类Fib
,加入__call__
方法
class Fib(object):
def __init__(self):
self.res=[]
def __call__(self,num):
self.num=num
a,b=0,1
for i in range(num):
self.res.append(a)
a,b=b,a+b
return self.res
f=Fib()
print(f(10)) # 可以像函数一样调用
输出:
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
为了便于管理自定义的内容,可以将模块根据特定规则划分到包中
导入格式:from 包 import 模块
包必须包含__init__.py
文件,模块文件没有__init__.py
文件
定义一个叫tools
的模块,模块名:tools.py
# tools.py
def say_hello(name):
print('你好啊{}'.format(name))
def say_goodbye(name):
print('拜拜{}'.format(name))
import 模块名1 [as 别名1], 模块名2 [as 别名2],…
from 模块名 import 成员名1 [as 别名1],成员名2 [as 别名2],…
导入官方模块不需要考虑路径问题,导入自定义模块需要考虑路径(详情见:导入模块的路径)
导入整个模块
import MODULE
导入模块的部分属性或函数
from PACKAGE import MODULE
导入模块中的所有内容
from PACKAGE import *
为了防止导入的函数与本文件的函数冲突,有两种方法解决:
from PACKAGE import MODULE as NAME
把导入的内容进行重命名如使用两种方法导入math
模块的sin(),cos()
函数
# 从模块导入所有类
from math import sin,cos,pi
sin(pi/2)
cos(pi/3)
# 导入整个模块
import math
math.sin(pi/2)
math.cos(pi/3)
# 使用别名
from math import sin as s,pi
s(pi/2)
使用sys
模块中的path
变量,可以得到一个路径列表,导入模块的时候会搜索这个路径列表,如果想要添加路径,可以给sys.path
赋值
import sys # 或from sys import path
sys.path.append('../') # path.append('../')