美文网首页
Python基础语法-2

Python基础语法-2

作者: xiaohan_zhang | 来源:发表于2019-07-24 09:16 被阅读0次
    • class
      class后面紧接着是类名,类名命名规则大驼峰,紧接着是(object),表示该类是从哪个类继承下来的

    定义类格式:

    class 类名:
        def 方法名(self, 参数):
            pass
    

    创建对象格式:

    对象变量 = 类名()
    
    1. 初始化方法
      使用类名()创建对象时,会自动调用init方法
      init方法用来定义一个类具有哪些属性
    class Person(object):
    
        def __init__(self):
            print("初始化方法")
            self.name = "Naruto"
    
    
    person = Person()
    print(person.name)
    
    
    class Cat(object):
    
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def eat(self):
            print('%s爱吃鱼' % self.name)
    
    
    cat = Cat('Tom', 2)
    print(cat.name)
    cat.eat()
    
    # 在类的外部给对象增加属性(不推荐)
    cat.gender = "公"
    
    1. 内置方法del
      对象从内存中被销毁前,会自动调用del
    2. 内置方法str
      必须返回一个字符串
      如果在开发中,使用print输出一个对象时,希望打印自定义内容,可以使用str方法。
    class Dog(object):
    
        def __init__(self, name):
            self.name = name
            print('%s 来喽' % self.name)
    
        def __del__(self):
            print("%s 走了" % self.name)
    
        def __str__(self):
    
            return '我是小狗%s' % self.name
    
    
    dog = Dog('xiaohei') 
    
    1. 访问限制
      在Python中,实例的变量名如果以__开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问。
    class Students(object):
    
        def __init__(self, name, score):
            # 无法从外部访问实例变量.__name和实例变量.__score
            self.__name = name
            self.__score = score
    
        def get_name(self):
            return self.__name
    
        def get_score(self):
            return self.__score
    
        def set_score(self, score):
            if 0 <= score <= 100:
                self.__score = score
            else:
                # raise ValueError('bad score')
                self.__score = 0
    
    
    student = Students('Naruto', 60)
    print('%s: %s' % (student.get_name(), student.get_score()))
    
    面向对象三大特性

    封装: 根据 职责 将 属性 和 方法 封装 到一个抽象的 类 中;
    继承: 实现代码的重用,相同的代码不需要重复的编写;
    多态: 不同的对象调用相同的方法,产生不同的执行结果,增加代码的灵活度;

    • 封装
      封装 是面向对象编程的一大特点;
      面向对象编程的 第一步 —— 将 属性 和 方法 封装 到一个抽象的 类 中;
      外界 使用 类 创建 对象,然后 让对象调用方法;
      对象方法的细节 都被 封装 在 类的内部。
    """
    需求:
    1.士兵许三多有一把AK47
    2.士兵可以开火
    3.枪能够发射子弹
    4.枪装填子弹 可增加子弹数量
    """
    class Gun(object):
        def __init__(self, model):
            self.model = model
            self.buttet_count = 0
    
        def shoot(self):
            if self.buttet_count > 0:
                self.buttet_count -= 1
                print("射击")
            else:
                print("%s没子弹" % self.model)
    
        def add_bullet(self, count):
            print("装子弹")
            self.buttet_count += count
    
    
    class Soldier(object):
        def __init__(self, name):
            self.name = name
            self.gun = None
    
        def add_gun(self, gun):
            self.gun = gun
    
        def add_bullet(self, count):
            if self.gun is None:
                print("没有枪")
            else:
                self.gun.add_bullet(count)
    
        def fire(self):
            if self.gun is None:
                print("士兵没有枪")
            else:
                print("开火")
                self.gun.shoot()
    
    
    gun = Gun("AK47")
    soldier = Soldier("许三多")
    soldier.add_gun(gun)
    soldier.add_bullet(20)
    soldier.fire()
    
    • 继承
      1.子类对象不能在自己的方法内部,直接访问父类的 私有方法 或 私有属性;
      2.子类对象可以通过父类的公有方法 间接 访问到 私有方法 和 私有属性。
    1. 单继承
    class Animal(object):
    
        def __init__(self, name):
            self.name = name
    
        def eat(self):
            print("%s 吃" % self.name)
    
        def drink(self):
            print("%s 喝" % self.name)
    
        def run(self):
            print("%s 跑" % self.name)
    
        def sleep(self):
            print("%s 睡" % self.name)
    
    
    class Dog(Animal):
    
        def bark(self):
            print("%s 叫" % self.name)
    
        # 子类对象不能调用父类的私有方法
        def __test(self):
            print("Dog的私有方法")
    
        # 子类对象可以通过调用父类的公有方法,间接调用父类的私有方法
        def ttt(self):
            print("Dog的公有方法")
            self.__test()
    
    
    class Cat(Animal):
    
        def catch(self):
            print("%s 抓老鼠" % self.name)
    
    
    class RoaringDog(Dog):
        def fly(self):
            print("%s 会飞" % self.name)
    
        # 重写(override)父类方法
        def bark(self):
            # super().bark()     # 同时执行父类中的方法
            print("%s叫的和神一样" % self.name)
    
    
    dog = Dog("旺财")
    dog.eat()
    dog.bark()
    dog.ttt()
    
    cat = Cat("汤姆")
    cat.drink()
    cat.catch()
    
    xtq = RoaringDog('哮天犬')
    xtq.run()
    xtq.fly()
    xtq.bark()
    
    1. 多继承
      子类可以拥有多个父类,并且具有所有父类的属性和方法
      注意:如果父类之间存在同名的属性或方法,应该避免使用多继承
    class A(object):
    
        def test(self):
            print("A的test()方法")
    
    
    class B(object):
    
        def demo(self):
            print("B的demo()方法")
    
    
    class C(A, B):
    
        pass
    
    
    c = C()
    c.test()
    c.demo()
    
    • 多态
      不同的子类对象调用相同的父类方法,产生不同的执行结果。
      1.多态可以增加代码的灵活度
      2.以继承 和 重写父类方法 为前提
      3.是调用方法的技巧,不会影响到类内部设计
    class Dog(object):
        def __init__(self, name):
            self.name = name
    
        def game(self):
            print("%s蹦蹦跳跳的玩耍~" % self.name)
    
    
    class XiaoTianQuan(Dog):
    
        def game(self):
            print("%s飞到天上去玩耍" % self.name)
    
    
    class Person(object):
        def __init__(self, name):
            self.name = name
    
        def game_with_dog(self, dog):
            print("%s 和 %s 快乐的玩耍" % (self.name, dog.name))
            dog.game()
    
    
    wangcai = Dog('旺财')
    xiaolan = Person('小兰')
    xiaolan.game_with_dog(wangcai)
    
    xiaotianquan = XiaoTianQuan('哮天犬')
    xiaohong = Person('小红')
    xiaolan.game_with_dog(xiaotianquan)
    
    • 类属性 类方法 静态方法
    1. 类属性
      实例属性属于各个实例所有,互不干扰;
      类属性属于类所有,所有实例共享一个属性;
      不要对实例属性和类属性使用相同的名字,否则将产生难以发现的错误.

    访问类属性方法:
    1.类名.类属性
    2.对象.类属性(不推荐)
    注意:如果使用 对象.类属性 = 值 赋值语句,只会给对象添加一个属性,而不会影响到类属性的值

    1. 类方法
      类方法就是针对类对象定义的方法;
      在类方法内部可以直接访问类对象或其它类方法;
      类方法需要用@classmethod修饰器来标识,告诉解释器 这是一个类方法;
    语法:
    @classmethod
    def 类方法名(cls)
        pass
    

    注:类方法的第一个参数是cls,类似实例方法的self,在方法内部可以通过cls访问类属性,也可以通过cls调用其它类方法.

    class Tool(object):
    
        count = 0
    
        @classmethod
        def show_tool_count(cls):
            print('有%d个工具' % cls.count)
    
        def __init__(self, name):
            self.name = name
            Tool.count += 1
    
    
    tool1 = Tool('斧头')
    print('有%d个工具' % Tool.count)
    tool2 = Tool('锤子')
    print('有%d个工具' % Tool.count)
    
    Tool.show_tool_count()
    
    1. 静态方法
      使用场景:在开发时,如果需要在类中封装一个方法,这个方法:
      不需要 访问实例属性 或 调用实例方法,也不需要 访问类属性 或 调用类方法,
      可以将这个方法封装为静态方法
    语法:
    @staticmethod
    def 静态方法名():
        pass
        
    调用方法: 类名.静态方法()
    
    class Dog(object):
        dog_count = 0
    
        @staticmethod
        def run():
            print("🏃")
    
    
    Dog.run()
    

    实例方法:方法内部需要访问实例属性,实例方法内部可以使用 类名. 访问类属性
    类方法:方法内部只需要访问类属性
    静态方法:方法内部不需要访问 实例属性 和 类属性

    • 单例Singleton
      目的 —— 让 类 创建的对象,在系统中 只有 唯一的一个实例
      每一次执行 类名() 返回的对象,内存地址是相同的

    使用类名创建对象时,会先调用new 方法为对象分配内存空间
    new是一个由object基类提供的内置的静态方法,主要作用有两个:
    1.在内存中为对象分配内存空间
    2.返回对象的引用
    python解释器获得对象的引用后,将引用作为第一个参数传递给init方法
    注:new 是静态方法,需主动传递cls参数

    class MusicPlayer(object):
    
        instance = None
        init_flag = False
    
        def __new__(cls, *args, **kwargs):
    
            if cls.instance is None:
                cls.instance = super().__new__(cls)
                print("创建对象,分配内存空间")
            return cls.instance
    
        def __init__(self):
            # 初始化只执行一次
            if MusicPlayer.init_flag:
                return
    
            MusicPlayer.init_flag = True
            print("播放器初始化")
    
    
    player = MusicPlayer()
    print(player)
    player2 = MusicPlayer()
    print(player2)
    
    • 异常Exception
      在程序开发中,如果 对某些代码的执行不能确定是否正确,可以增加 try(尝试) 来 捕获异常
      捕获异常最简单的语法格式:
    try:
        尝试执行的代码
    except:
        出现错误的处理
    
    1. 根据错误类型捕获异常
    try:
        num = int(input("请输入一个整数:"))
        result = 8 / num
    except ValueError as e:
        print('except:', e)
    except ZeroDivisionError as e:
        print('except:', e)
    except Exception as e:
        print("未知错误 %s" % e)
    else:
        #  没有异常才会执行的代码
        print(result)
    finally:
        # 无论是否有异常 都会执行的代码
        print("-" * 50)
    
    1. 异常的传递
      当方法的执行出现异常,会将异常传递给调用方法的一方;
      如果传递到主程序,仍然没有异常处理,程序才会被终止;
      提示:
      在开发中,可以在主函数中增加异常捕获,在主函数中调用的其它函数,只要出现异常,就会传递到主函数的异常捕获中;
      这样就不需要在代码中增加大量的异常捕获,能够保证代码的整洁;
    def demo1():
        return int(input("请输入一个整数:"))
    
    
    def demo2():
        return demo1()
    
    
    try:
        demo2()
    except ValueError:
        print("请输入正确整数")
    except Exception as e:
        print('未知错误 %s' % e)
    
    1. 抛出raise异常
      在开发中,除了代码执行出错会抛出异常之外,还可以根据应用程序特有的业务需求主动抛出异常
      步骤:
      1.创建一个Exception 异常类
      2.使用raise关键字抛出异常对象
    def input_password():
        password = input("请输入密码:")
        if len(password) >= 8:
            return password
    
        raise Exception("密码长度不够")
    
    
    try:
        print(input_password())
    except Exception as e:
        print(e)
    
    • 模块和包
    1. 模块
      每一个以扩展名 py 结尾的 Python 源代码文件都是一个 模块;
      模块名 同样也是一个 标识符,需要符合标识符的命名规则;
      在模块中定义的 全局变量 、函数、类 都是提供给外界直接使用的 工具;
      模块 就好比是 工具包,要想使用这个工具包中的工具,就需要先 导入 这个模块;

    模块的导入:
    import 模块1
    import 模块2

    通过 模块名. 使用模块提供的全局变量、方法、类

    模块导入时指定别名: import 模块1 as 模块别名

    局部导入from...import:

    如果希望从一个模块中导入部分工具,可以使用from...import 的方式
    import 模块名是一次性将模块中所有工具全部导入,并且通过模块名/别名访问

    from 模块名1 import 工具名

    导入之后可以直接使用模块提供的工具--全局变量、函数、类
    注:如果两个模块,存在同名的函数,后导入模块的函数会覆盖先导入模块的函数

    从模块中导入所有工具(知道)
    from...import *

    在导入模块文件时,文件中所有没有缩进的代码都会被执行一遍
    name 属性可以做到,测试模块的代码只在测试情况下被运行,而在被导入时不会执行
    name是python的内置属性,记录着一个字符串
    如果是被其它文件导入的,name就是文件名

    py_17_test_module.py

    def say_hello():
        print("hello!!!")
    
    
    def say_hi():
        print("hi???")
    
    
    # 被其它文件导入时,不会被执行
    if __name__ == "__main__":
        print("小米开发的模块")
    
    import py_17_test_module
    import py_17_test_module as tm
    from py_17_test_module import say_hello
    
    py_17_test_module.say_hello()
    tm.say_hi()
    say_hello()
    
    # 模块路径
    print(py_17_test_module.__file__)
    
    print(py_17_test_module.__name__)    # py_17_testModule
    print(__name__)     # __main__
    

    1. 包是一个包含了多个模块的特殊目录
      目录下有一个特殊文件 init.py
      包名的命名方式与变量名一致,小写字母+_
      使用 import 包名 可以一次性导入包中的所有模块

    _init.py
    要在外界使用包中的模块,需要在_init.py中指定对外界提供的模块列表

    # __init__.py内容
    from . import py_17_send_message
    from . import py_17_receive_message
    
    import py_17_message
    
    py_17_message.py_17_send_message.send("你是🐷吗")
    txt = py_17_message.py_17_receive_message.receive()
    
    1. 发布模块(知道)
      步骤:
      1)创建setup.py文件
    from distutils.core import setup
    
    setup(name="xh_message",    # 包名
          version="1.0.0",      # 版本号
          description="发送和接收消息模块",  # 描述信息
          long_description="完整的发送和接收消息模块", # 完整的描述信息
          author="xiaohan",     # 作者
          author_email="xiaohan@gamil.com",  # 作者邮箱
          url="www.xiaohan.com",    # 主页
          py_17_message=["py_17_message.py_17_send_message", "py_17_message.py_17_receive_message"]) # 模块中包含的文件名称
    

    2)构建模块

    终端:$ python3 setup.py build
    

    3)生成发布压缩包

    终端:$ python3 setup.py sdist
    

    安装模块
    $ tar -zxvf py_17_message-1.0.0.tar.gz
    $ sudo python3 setup.py install

    卸载模块
    直接从安装目录将模块目录删除即可
    $ cd /usr/local/lib/python3/dist-packages/
    $ sudo rm -r py_17_message*
    可以通过file内置属性获取模块所在路径
    $ ipython3
    $ import py_17_message
    $ py_17_message.file

    • 文件
    1. 文件的基本操作
    函数/方法 说明
    open 打开文件 并且返回文件操作对象
    read 将文件内容读取到内存
    write 将指定内容写入文件
    close 关闭文件

    注:
    open: 函数默认以只读方式打开文件
    如果文件存在,返回文件操作对象
    如果文件不存在,会抛出异常
    read: 方法可以一次性读入并返回文件的所有内容
    close: 方法负责关闭文件

    try:
        file = open("text")     # 打开文件(默认只读方式)
        text = file.read()      # 读取文件
        text2 = file.read()     # 已经读取过来,文件指针在末尾,读取不到任何内容
        file.close()            # 关闭文件
    
        print(text)
        print(len(text2))
    except FileNotFoundError:
        print("文件不存在")
    except Exception as e:
        print("未知错误 %s" % e)
    

    open方法参数:
    1.第一个参数是要打开的文件名
    2.第二个参数是访问方式

    参数 说明
    r 以只读方式打开。文件指针会放在文件开头,如果文件不存在会抛出异常
    w 以只写方式打开。如果文件存在会被覆盖,如果文件不存在,创建新文件
    a 以追加方式打开。如果文件已存在,文件指针会方法在文件结尾;如果文件不存在,会创建文件
    r+ 以读写方式打开。文件指针会放在文件开头,如果文件不存在会抛出异常
    w+ 以读写方式打开。如果文件存在会被覆盖,如果文件不存在,创建新文件
    a+ 以读写方式打开。如果文件已存在,文件指针会方法在文件结尾;如果文件不存在,会创建文件
    file = open("text", "a")
    file.write("hello")
    file.close()
    
    file = open("text")
    print(file.read())
    file.close()
    
    1. 按行读取文件内容
      readline 方法可以一次读取一行内容
      方法执行后,会把文件指针移动到下一行,准备再次读取
    # 读取大文件
    file = open("text")
    while True:
        text = file.readline()
        if not text:
            break
        print(text, end="")
    
    file.close()
    
    1. 文件指针(知道)
      文件指针 标记从哪个位置开始读取数据
      第一次打开文件时,通常文件指针会指向文件的开始位置
      当执行了read方法后,文件指针会移动到文件内容的末尾
    2. 复制文件
    # 小文件复制
    file_read = open("text")
    file_write = open("text[副本]", "w")
    
    text = file_read.read()
    file_write.write(text)
    
    file_read.close()
    file_write.close()
    
    file = open("text[副本]")
    print(file.read())
    
    # 大文件复制
    file_read = open("text")
    file_write = open("text[副本]", "w")
    
    while True:
        text = file_read.readline()
        if not text:
            break
    
        file_write.write(text)
    
    file_read.close()
    file_write.close()
    
    file = open("text[副本]")
    print(file.read())
    
    1. 文件\目录的常用管理操作
      需要导入os模块
      文件操作:
    方法名 说明 示例
    rename 重命名文件 os.rename(源文件名, 目标文件名)
    remove 删除文件 os.remove(文件名)
    path.isfile 判断是否是文件 os.path.isfile(路径)

    目录操作:

    方法名 说明 示例
    listdir 目录列表 os.listdir(目录名)
    mkdir 创建目录 os.mkdir(目录名)
    rmdir 删除目录 os.rmdir(目录名)
    getcwd 获取当前目录 os.getcwd()
    chdir 修改工作目录 os.chdir(目标目录)
    path.isdir 判断是否是目录 os.path.isdir(路径)
    print(os.getcwd())
    # os.mkdir("测试")
    os.remove(os.getcwd() + "/text[副本]")
    
    • eval
      eval函数 可以将字符串当成有效的表达式来求值,并返回计算结果
      注:开发时,不要使用eval直接转换input的结果
    # 基本数学计算
    eval("1 + 1")       # 2
    # 字符串重复
    eval("'+' * 10")    # ++++++++++
    # 字符串转列表
    type(eval("[1,2,3,4]"))  # <class 'list'>
    # 字符串转字典
    type(eval("{'name':'xiaolan', 'age':'16'}"))  # <class 'dict'>
    
    str = input("请输入算数题:")
    print(eval(str))
    
    """
    __import__('os').system('ls')
    # 等价代码
    import os
    os.system("终端命令")
    
    执行成功,返回0
    执行失败,返回错误信息
    """
    eval("__import__('os').system('ls')")
    

    相关文章

      网友评论

          本文标题:Python基础语法-2

          本文链接:https://www.haomeiwen.com/subject/scktrctx.html