python3之包和模组、面向对象、错误处理

模组

  • 在Python中,一个.py文件就称之为一个模块(Module)。 使用模块可以大大提高代码的可维护性和可复用性。
  • 使用模块还可以避免函数名和变量名冲突。相同名字的函数和变量完全可以分别存在不同的模块中。
  • 自己创建模块时要注意命名,不能和Python自带的模块名称冲突。
" a test module "  # 模块的文档注释

__author__ = "Michael Liao"  # 作者

import sys


def test():
    args = sys.argv
    if len(args) == 1:
        print("Hello, world!")
    elif len(args) == 2:
        print("Hello, %s!" % args[1])
    else:
        print("Too many arguments!")


# 命令行运行模块文件时,Python解释器把变量__name__置为__main__,而在其他地方导入该模块时,if判断将失败,
# 因此,这种if测试可以让一个模块通过命令行运行时执行一些额外的代码,最常见的就是运行测试。
if __name__ == "__main__":
    test()

作用域

  • 正常的函数和变量名是公开的(public),可以被直接引用
  • 类似__author__、__name__、__doc__ 这样的变量是特殊变量,可以被直接引用
  • 类似_xxx和__xxx这样的函数或变量就是非公开的(private),从编程规范和习惯上不应该引用private函数或变量。

模块搜索路径

默认情况下,Python解释器会搜索当前目录、所有已安装的内置模块和第三方模块,搜索路径存放在sys模块的path变量中
要添加自己的搜索目录,有两种方法:
  • 直接修改sys.path,此种方法在运行时修改,运行结束后失效:  sys.path.append('/path/to/packages')
  • 设置环境变量PYTHONPATH

  • 为了避免模块名冲突,Python又引入了按目录来组织模块的方法,称为包(Package)。
  • 引入了包以后,只要顶层的包名不与其它包冲突,那所有模块都不会与其它包冲突。
  • 每一个包目录下面都会有一个__init__.py的文件,这个文件是必须存在的,否则,Python就把这个目录当成普通目录,而不是一个包。
  • __init__.py可以是空文件,也可以有Python代码,因为__init__.py本身就是一个模块,而它的模块名就是包名。

面向对象

# 类定义 继承自object类
class Human(object):
    name = "Human"

    # private 属性
    __money = 100

    # 初始化实例方法
    def __init__(self, name, money):
        self.name = name
        self.__money = money
        self.sing = True

    def get_money(self):
        return self.__money

    def set_money(self, money):
        self.__money = money

    # 实例方法
    def eat(self, food):
        print(self.name, "eat", food)

    # 类方法 通过@classmethod装饰器实现,类方法中只能访问类变量,不能访问实例变量;通过cls参数传递当前类对象,不需要实例化。
    @classmethod
    def walk(cls, speed):
        print(cls.name, "walk", speed)

    # 静态方法 通过@staticmethod装饰器实现,在静态方法中无法访问类和实例中的任何属性;调用时并不需要传递类或实例。
    # 定义在类中的普通函数
    @staticmethod
    def sleep(hour):
        print(Human.name, "sleep", hour)


# 子类 继承自Human类
class Student(Human):
    name = "Student"

    # @property装饰器将一个方法变成属性使用
    @property
    def birth(self):
        return self._birth

    @birth.setter
    def birth(self, value):
        self._birth = value

    # 限制允许绑定的属性名称,仅对当前类实例起作用,子类实例不起作用
    __slots__ = ("grade", "age")

    def eat(self, food):
        pass
        print(self.name, "eat", food)

    def drink(self, drink):
        print(self.name, "drink", drink)


# MixIn给一个类增加当前类的功能,子类可以通过多重继承来组合多个MixIn的功能,而不用设计多层次的复杂的继承关系。
class CourseNatureMixIn:
    def learn_nature(self):
        print("learn nature class")


# 多继承
class Pupil(Student, CourseNatureMixIn):
    name = "Pupil"


# 实例变量访问
m = Student("小明", 300)
print(dir(m))  # 获取实例的所有属性和方法
print(m.name, m.sing, m.get_money())  # 小明 True 300

m.birth = "2020-01-01"
print(m.birth, getattr(m, "birth"))  # 2020-01-01 2020-01-01

# 实例动态添加属性
m.age = 9
print(m.age, hasattr(m, "age"), getattr(m, "age"))  # 9 True 9
m.grade = 5
print(m.grade, hasattr(m, "grade"), getattr(m, "grade"))  # 5 True 5

print(isinstance(m, Student), isinstance(m, Human), isinstance(m, object))  # True True True
print(issubclass(Student, Human))  # True

print(hasattr(m, "eat"), hasattr(m, "name"), hasattr(m, "__money"))  # True True False
print(getattr(m, "name"), getattr(m, "age", 20))  # 小明 9
setattr(m, "name", "小青")
print(getattr(m, "name"))  # 小青


m.eat("饺子")  # 小青 eat 饺子
m.walk("很快")  # Student walk 很快
m.sleep("8小时")  # Human sleep 8小时

w = Pupil("小王", 100)
w.age = 10
print(w.age, hasattr(w, "age"), getattr(w, "age"))  # 10 True 10
w.level = 5
print(w.level, hasattr(w, "level"), getattr(w, "level"))  # 5 True 5

w.learn_nature()  # learn nature class

# 类变量访问
print(Student.name, Human.name)  # Student Human
Student.eat(m, "大米")  # 小青 eat 大米
Student.walk("很慢")  # Student walk 很慢
Student.sleep("7.5小时")  # Human sleep 7.5小时

错误处理

import logging

try:
    raise ValueError("value error")  # 抛出异常
except (ValueError, OSError) as err:  # 处理指定类型异常
    print("出现异常")
    print(err)
except:
    print("处理全部其它异常")  # 处理全部其它异常
else:
    print("没有异常发生")  # 没有异常发生
finally:
    print("必须执行")  # 必须执行的代码

# 调试方法1
try:
    a = 1
    b = 0
    print(a, b)
    x = a / b
except ZeroDivisionError as err:
    print(err)  # division by zero

# 调试方法2
try:
    a = 1
    b = 0
    assert b != 0, "b=0"  # 断言 AssertionError b=0
    x = a / b
except AssertionError as err:
    print(err)  # b=0

# 调试方法3:使用logging
# 可以指定记录信息的级别,有debug、info、warning、error等几个级别
logging.basicConfig(level=logging.INFO)
try:
    aa = 1
    bb = 0
    logging.info("bb={}".format(bb))  # INFO:root:bb=0
    x = aa / bb
except ZeroDivisionError as err:
    print(err)

 

posted @   carol2014  阅读(26)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示