【廖雪峰Python教程】学习笔记三 (模块作用域和类的私有变量)

Life is short, you need Python.

完整教程廖雪峰的官方网站

在学习廖雪峰老师的Python教程,记一下笔记。

1、模块

先看一个例子:

#hello.py
print("hello,world")
if __name__ == '__main__':
    print("正在运行%s模块." % "hello")
else:
    print("%s模块被导入使用." % "hello")

直接运行hello.py,运行结果:

hello,world
正在运行hello模块.

同目录下的其他文件导入hello.py模块:

import hello

运行结果:

hello,world
hello模块被导入使用.

简单来说:在Python中,一个.py文件就称之为一个模块(Module)。模块提高了代码的可维护性,编写代码不必从零开始。

举个例子,一个abc.py的文件就是一个名字叫abc的模块,一个xyz.py的文件就是一个名字叫xyz的模块。

现在,假设我们的abc和xyz这两个模块名字与其他模块冲突了,于是我们可以通过包来组织模块,避免冲突。方法是选择一个顶层包名,比如mycompany,按照如下目录存放:

mycompany
├─ __init__.py
├─ abc.py
└─ xyz.py
引入了包以后,只要顶层的包名不与别人冲突,那所有模块都不会与别人冲突。现在,abc.py模块的名字就变成了mycompany.abc,类似的,xyz.py的模块名变成了mycompany.xyz。

请注意,每一个包目录下面都会有一个__init__.py的文件,这个文件是必须存在的,否则,Python就把这个目录当成普通目录,而不是一个包。__init__.py可以是空文件,也可以有Python代码,因为__init__.py本身就是一个模块,而它的模块名就是mycompany。

类似的,可以有多级目录,组成多级层次的包结构。

在一个模块中,我们可能会定义很多函数和变量,但有的函数和变量我们希望给别人使用,有的函数和变量我们希望仅仅在模块内部使用。在Python中,是通过_前缀来实现的。

正常的函数和变量名是公开的(public),可以被直接引用,比如:abc,x123,PI等;

类似__xxx__这样的变量是特殊变量,可以被直接引用,但是有特殊用途,比如__author__,__name__就是特殊变量.

类似_xxx和__xxx这样的函数或变量就是非公开的(private),不应该被直接引用,比如_abc,__abc等;

之所以我们说,private函数和变量“不应该”被直接引用,而不是“不能”被直接引用,是因为Python并没有一种方法可以完全限制访问private函数或变量。

关于if __name__ == ‘__main__’:
如果 import 一个模块,那么模块__name__ 的值通常为模块文件名,不带路径或者文件扩展名。如果直接运行模块, __name__ 的值将是一个特别缺省"__main__"。

2、类的私有变量

如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__,在Python中,实例的变量名如果以__开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问

class Student():

    def __init__(self, name, score):
        self.__name=name
        self.__score=score

    def printInfo(self):
        print(self.__name)
        print(self.__score)

student=Student("XiaoMing",90)
print(student.__name)  #会报错,AttributeError: 'Student' object has no attribute '__name'
#可以通过类中的方法调用,不能直接调用私有变量

有些时候,你会看到以一个下划线开头的实例变量名,比如_name,这样的实例变量外部是可以访问的,但是,按照约定俗成的规定,当你看到这样的变量时,意思就是,“虽然我可以被访问,但是,请把我视为私有变量,不要随意访问”。

双下划线开头的实例变量是不是一定不能从外部访问呢?其实也不是。不能直接访问__name是因为Python解释器对外把__name变量改成了_Student__name,所以,仍然可以通过_Student__name来访问__name变量:
但是强烈建议你不要这么干,因为不同版本的Python解释器可能会把__name改成不同的变量名。

总的来说就是,Python本身没有任何机制阻止你干坏事,一切全靠自觉。

补充:

class Student():

    def __init__(self, name, score):
        self.__name=name
        self.__score=score

    def printInfo(self):
        print(self.__name)
        print(self.__score)

student=Student("XiaoMing",90)
student.__name="LiMing"   #看似更改了原来的__name私有变量,其实只是为student新增了一个__name变量
#实际上这个__name变量和class内部的__name变量不是一个变量!内部的__name变量已经被Python解释器自动改成了_Student__name
print(student.__name)
student.printInfo()

运行结果:
LiMing
XiaoMing
90

本文只是针对个人的一个知识点总结,详细完整的知识点请参考廖雪峰老师的网站教程。

点击前往:廖雪峰的官方网站

发布了17 篇原创文章 · 获赞 24 · 访问量 1925

猜你喜欢

转载自blog.csdn.net/qq_45271256/article/details/103269540
今日推荐