python3学习---08面向对象、作用域

# python3 file文件方法

#open方法
'''
Python open() 方法用于打开一个文件,并返回文件对象,在对文件进行处理过程都需要使用到这个函数,如果该文件无法被打开,会抛出 OSError。

注意:使用 open() 方法一定要保证关闭文件对象,即调用 close() 方法。

open() 函数常用形式是接收两个参数:文件名(file)和模式(mode)。
'''
#上次学习了open的基本格式,这里就不多赘述
#f=open(f'C:\Users\zxy\Desktop\fileTest.txt','r')

#open方法完整的参数列表
#open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
#点击源码可以看到 这些参数都是有默认值的,就是使用时可以不指定
'''
file: 必需,文件路径(相对或者绝对路径)。
mode: 可选,文件打开模式
buffering: 设置缓冲
encoding: 一般使用utf8
errors: 报错级别
newline: 区分换行符
closefd: 传入的file参数类型
opener: 设置自定义开启器,开启器的返回值必须是一个打开的文件描述符。
'''
# file对象的一些常用方法

#close() 每次创建文件对象后,在相关操作完成后,一定要使用close方法

#flush() 刷新缓冲区 直接把内部缓冲区的数据立刻写入文件, 而不是被动的等待输出缓冲区写入。

# fileno 返回一个整型的文件描述符(file descriptor FD 整型), 可以用在如os模块的read方法等一些底层操作上。
# f=open(r'C:\Users\zxy\Desktop\fileTest.txt','wb')
# print(f.name) #输出文件名 # C:\Users\zxy\Desktop\fileTest.txt
# print(f.fileno()) #输出文件描述符 3
# f.close()

# read() ,readline(),readlines

#seek()移动文件读取指针到指定位置
f=open(r'C:\Users\zxy\Desktop\fileTest.txt','rb+')
num=f.write(b'0123456789abcd')
print(num) # 14
a1=f.seek(5)
print(a1) #5
a2=f.read(1) #读取一个字节 如果没有移动读取指针,应该输出0才对,说明读取指针移动了5
print(a2) #b'5'

# tell 返回文件当前位置
print(f.tell()) # 6 读取指针到6了
f.close()

# truncate(size) 截断文件 从文件的首行首字符开始截断,截断文件为 size 个字符,无 size 表示从当前位置截断;截断之后后面的所有字符被删除,

# write ,writelines 写入文件
#python3 错误与异常

# 语法错误
'''
语法错误就是语法格式都不对,一般用ide编写的时候会爆红
'''

#异常

'''
即便 Python 程序的语法是正确的,在运行它的时候,也有可能发生错误。运行期检测到的错误被称为异常。

大多数的异常都不会被程序处理,都以错误信息的形式展现在这里:
'''

#ex:
# print(1/0)
'''
Traceback (most recent call last):
  File "F:\PycharmProjects\pythonStudy\study08\02errorAndExceptionTest.py", line 17, in 
    print(1/0)
ZeroDivisionError: division by zero
'''
# print(4*a)
'''
Traceback (most recent call last):
  File "F:\PycharmProjects\pythonStudy\study08\02errorAndExceptionTest.py", line 24, in 
    print(4*a)
NameError: name 'a' is not defined
'''

# 异常处理
'''
java中使用 try catch 
python3中 异常处理使用的是 try except
'''
#ex:
try:
    a=1/0
    print(a)
except:
    print("0不能作为除数")
#0不能作为除数

# try/except....else
'''
try/except 语句还有一个可选的 else 子句,如果使用这个子句,那么必须放在所有的 except 子句之后。

else 子句将在 try 子句没有发生任何异常的时候执行。
'''

try:
    a=100/5
    print(a) # 20.0
except:
    print("0不能作为除数")
else:
    print(f"除法结束,结果为{a}") # 除法结束,结果为20.0

try:
    a = 100 / 0
    print(a)
except:
    print("0不能作为除数") #0不能作为除数
else:
    print(f"除法结束,结果为{a}")

# try -finally
# 这个就比较好理解了,一定会执行的代码,一般类似于文件操作或者一些涉及到释放资源的操作,都会放在finally里


# 抛出异常
#使用raise抛出异常
# x=10
# if x>5:
#     raise Exception('x大于5!')
'''
Traceback (most recent call last):
  File "F:\PycharmProjects\pythonStudy\study08\02errorAndExceptionTest.py", line 76, in 
    raise Exception('x大于5!')
Exception: x大于5!
'''
# 用户自定义异常
'''
你可以通过创建一个新的异常类来拥有自己的异常。异常类继承自 Exception 类,可以直接继承,或者间接继承
继承的概念 有java基础很容易理解,只不过python中的继承还没有学过 之后会学 这里先不探究
'''
# class myError(Exception):
#     def __init__(self,value):
#         self.value=value
#     def __str__(self):
#         return repr(self.value)

# python 断言
'''
语法格式为: assert expression

等价于
if not expression:
    raise AssertionError

'''
# import sys
# assert ('linux' in sys.platform), "该代码只能在 Linux 下执行"
'''
Traceback (most recent call last):
  File "F:\PycharmProjects\pythonStudy\study08\02errorAndExceptionTest.py", line 104, in 
    assert ('linux' in sys.platform), "该代码只能在 Linux 下执行"
AssertionError: 该代码只能在 Linux 下执行
'''
assert (1/0),'0不能作为除数'
'''
Traceback (most recent call last):
  File "F:\PycharmProjects\pythonStudy\study08\02errorAndExceptionTest.py", line 111, in 
    assert (1/0),'0不能作为除数'
ZeroDivisionError: division by zero
'''
# python 中的面向对象
# 有过java面向对象的底子,其实对python中的面向对象理解应该不是那么难 记住 python可以多继承
'''
类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
方法:类中定义的函数。
类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
数据成员:类变量或者实例变量用于处理类及其实例对象的相关的数据。
方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
局部变量:定义在方法中的变量,只作用于当前实例的类。
实例变量:在类的声明中,属性是用变量来表示的,这种变量就称为实例变量,实例变量就是一个用 self 修饰的变量。
继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟"是一个(is-a)"关系(例图,Dog是一个Animal)。
实例化:创建一个类的实例,类的具体对象。
对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。
'''

# 类定义
class Myclass:
    #基本属性
    name=''
    age=0
    #私有属性
    __height=180
    def say(self):
        print(fr"hello my name is {self.name}")
    #类有一个名为 __init__() 的特殊方法(构造方法),该方法在类实例化时会自动调用
    #构造方法可以分有参构造和无参构造
    def __init__(self,name,age):
        self.name=name
        self.age=age
    # def __int__(self):
    #     pass
    # 这里是错误的 python类只有一个构造函数
    #self 代表类的实例,而非类
    #类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称, 按照惯例它的名称是 self。
    def prt(self):
        print(self)
        print(self.__class__)
# 类对象
x=Myclass('zxy',18) #实例化Myclass这个类
print(x.name,x.age) # 访问类的属性 #zxy 18
x.say()# 类的方法 # hello my name is zxy
x.age=100
print(x.name,x.age) # 访问类的属性 #zxy 100

y=Myclass('test',60)
print(y.name,y.age) # test 60
#这里调用x,y两个实例的prt方法来查看一下区别
x.prt()
#<__main__.Myclass object at 0x0000025E140C3FD0>
#
print("----")
y.prt()
#<__main__.Myclass object at 0x0000025E140C3F10>
#
#可见 实例是不同实例,但是同一个类;这里可以类比java中的实例对象和类对象
# print(x.__height) # AttributeError: 'Myclass' object has no attribute '__height' 私有属性无法访问


#python支持多继承
'''
class DerivedClassName(Base1, Base2, Base3):
需要注意圆括号中父类的顺序,若是父类中有相同的方法名,而在子类使用时未指定,python从左至右搜索 即方法在子类中未找到时,从左到右查找父类中是否包含方法。
'''

#类属性与方法
'''
属性和方法都可以是私有的 用两个下划线定义  __name

在类的内部,使用 def 关键字来定义一个方法,与一般函数定义不同,类方法必须包含参数 self,且为第一个参数,self 代表的是类的实例。
self 的名字并不是规定死的,也可以使用 this,但是最好还是按照约定是用 self。
'''

# 类的专有方法
'''
__init__ : 构造函数,在生成对象时调用
__del__ : 析构函数,释放对象时使用
__repr__ : 打印,转换
__setitem__ : 按照索引赋值
__getitem__: 按照索引获取值
__len__: 获得长度
__cmp__: 比较运算
__call__: 函数调用
__add__: 加运算
__sub__: 减运算
__mul__: 乘运算
__truediv__: 除运算
__mod__: 求余运算
__pow__: 乘方
'''

# 运算符重载

#比如我们有个自定义类要相加
class Vector:
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def __str__(self):
        return 'Vector (%d, %d)' % (self.a, self.b)

    # def __add__(self, other):
    #     return Vector(self.a + other.a, self.b + other.b)


v1 = Vector(2, 10)
v2 = Vector(5, -2)
print(v1 + v2) # Vector (7, 8)
# 如果注释掉__add__的重写代码,则TypeError: unsupported operand type(s) for +: 'Vector' and 'Vector'
# python 命名空间与作用域
'''
命名空间(Namespace)是从名称到对象的映射,大部分的命名空间都是通过 Python 字典来实现的。

命名空间提供了在项目中避免名字冲突的一种方法。各个命名空间是独立的,没有任何关系的,所以一个命名空间中不能有重名,但不同的命名空间是可以重名而没有任何影响。

我们举一个计算机系统中的例子,一个文件夹(目录)中可以包含多个文件夹,每个文件夹中不能有相同的文件名,但不同文件夹中的文件可以重名。
'''

'''
内置名称(built-in names), Python 语言内置的名称,比如函数名 abs、char 和异常名称 BaseException、Exception 等等。
全局名称(global names),模块中定义的名称,记录了模块的变量,包括函数、类、其它导入的模块、模块级的变量和常量。
局部名称(local names),函数中定义的名称,记录了函数的变量,包括函数的参数和局部定义的变量。(类中定义的也是)
'''
#全局变量
var1=5
def function():
    var2=6 #局部变量
    def function2():
        var3=7 #内嵌的局部变量


'''
作用域

作用域就是一个 Python 程序可以直接访问命名空间的正文区域。
在一个 python 程序中,直接访问一个变量,会从内到外依次访问所有的作用域直到找到,否则会报未定义的错误。
Python 中,程序的变量并不是在哪个位置都可以访问的,访问权限决定于这个变量是在哪里赋值的。
变量的作用域决定了在哪一部分程序可以访问哪个特定的变量名称。Python的作用域一共有4种,分别是:
有四种作用域:
L(Local):最内层,包含局部变量,比如一个函数/方法内部。
E(Enclosing):包含了非局部(non-local)也非全局(non-global)的变量。比如两个嵌套函数,一个函数(或类) A 里面又包含了一个函数 B ,那么对于 B 中的名称来说 A 中的作用域就为 nonlocal。
G(Global):当前脚本的最外层,比如当前模块的全局变量。
B(Built-in): 包含了内建的变量/关键字等。,最后被搜索
规则顺序: L –> E –> G –>gt; B。
在局部找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,再者去内置中找。
'''

# global和nonlocal关键字
num = 1
def fun1():
    global num  # 需要使用 global 关键字声明
    print(num) #1
    num = 123
    print(num) #123
fun1()
print(num) #123

# nonlocal关键字声明
def outer():
    var = 10
    def inner():
        global var   # global关键字声明
        var = 100
        print(var) #100
    inner()
    print(var) #10
outer()


def outer():
    num = 10
    def inner():
        nonlocal num   # nonlocal关键字声明
        num = 100
        print(num) #100
    inner()
    print(num) #100
outer()


'''
简单理解:
全局作用域就是说白了模块(单个 .py 文件中)直接声明的变量。
#子类


'''
# 父类
class Parent:
    name=''
    age=0
    __height=180
    def __init__(self,name,age,height):
        self.name=name
        self.age=age
        self.__height=height
    def speak(self):
        print(f"我是{self.name},是父类。")
import parentClass
class Kid(parentClass.Parent):
    grade=''
    def __init__(self,name,age,height,grade):
        parentClass.Parent.__init__(self,name,age,height)
        self.grade=grade
    def speak(self):
        print(f"我是{self.name},是子类")

x=Kid('子类',18,180,"100分")
x.speak()# 我是子类,是子类
super(Kid,x).speak() # 我是子类,是父类。 调用父类方法(注意 ide是.不出来的)
y=parentClass.Parent('父类',50,190)
y.speak() # 我是父类,是父类。

你可能感兴趣的:(学习记录,python)