Python基础语法-2

2019-07-24  本文已影响0人  xiaohan_zhang

定义类格式:

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. 单继承
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()
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()

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

使用类名创建对象时,会先调用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)
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("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')")
上一篇下一篇

猜你喜欢

热点阅读