python课程回顾复习记录简要10

高级语法
1.封装性进阶
原先学习过对属性私有化,在类属性名前加双下划线(即__),只允许本类访问

class Computer(object):
    """
    给类添加object
    私有化属性 前边加__
    setter和getter
    """
    def __init__(self):
    	#私有化属性前边加__
        self.__brand="DEll"
    #setter方法
    def set_brand(self,brand):
        self.__brand=brand
    #getter方法
    def get_brand(self):
        return self.__brand
#创建对象
computer=Computer()
computer.set_brand("huawei")
print(computer.get_brand())

在这里插入图片描述
(1)形式为“xxxx”或“xxxx()”为公有的,如:公有变量、公有方法,在外部可直接访问;

class Computer(object):
    def __init__(self):
        # 公有属性
        self.brand = "小米"
        self.size = 8

    def show_info(self):

        print("品牌名称:", self.brand)
        print("内存大小:", self.size)
# 创建对象
computer = Computer()
# 访问属性 对象名.属性
print(computer.brand)
# 访问方法 对象名.方法()
computer.show_info()

在这里插入图片描述

(2)形式为“_xx”或“_xx()”–私有化[ 使用不多]。即前置单下划线,为私有化属性或方法,类对象和子类可以访问,且需要注意的是*若采用“from 模块名 import ”的形式导入不了该类私有化属性或方法

# coding:utf-8
class Computer(object):
    def __init__(self):
        # 私有属性
        self.__price=2

    def show_info(self):

        print("私有属性:",self.__price)
    def __fun(self):
        print("--私有方法--")
# 创建对象
computer = Computer()
# 访问私有化属性 对象名._类名__属性名
print("名字重整的方式访问私有属性:",computer._Computer__price)
#访问私有方法
fun=computer._Computer__fun
fun()

在这里插入图片描述
(4)形式为“xx”或“xx()”即前后双下划线,通常为 Python 系统提供的属性、模块或魔法方法,如:maininit()等,建议开发者不要以这种形式命名
(5)形式为“xx_”或“xx_()”即后置单下划线,通常是开发者用于避免与 Python 关键字冲突而命名的。

# coding:utf-8
"""
标识符的命名规则:
1.由字母、数字、下划线组成;
2.不能使用关键字作为命名;
3.开头不能是数字;
4.区分大小写、对大小写敏感;
5.对长度没有限制。
"""
a = 100
print(a)
_else = 100
print(_else)
return_ = 90
print(return_)

在这里插入图片描述
2**.属性property**
开头说的setter和getter方法处理时不太方便.原因:获取属性值之前,需要先设置属性值。步骤:①设置属性值,setter;②获取属性值,getter。
首先,从一个自定义类 Student 说起,给该类的年龄属性进行封装,即写 getter 与 setter 方法,此时需要对年龄属性进行私有化。

class Student(object):
    def __init__(self):
        self.__age = 0
    def set_age(self, age):
        # if 0 <= age and age <= 140:
        if 0 <= age <= 140:
            self.__age = age
        else:
            self.__age = 0
    # self.__age = age
    def get_age(self):
        return self.__age
# 使用 :创建对象
student = Student()
#设置属性
student.set_age(-18)
print("年龄值:",student.get_age())

可以使用一个较为简便的方式来升级上述案例并完成相同的功能,即使用 property(),语法格式如下:
公有属性名 = property(getter 方法名, setter 方法名)

class Student(object):
    def __init__(self):
        self.__age = 0
    def set_age(self, age):
        # if 0 <= age and age <= 140:
        if 0 <= age <= 140:
            self.__age = age
        else:
            self.__age = 0
    # self.__age = age
    def get_age(self):
        return self.__age
    #把setter getter方法的值放入一个公有属性中,property()
    age=property(get_age,set_age)
# 使用 :创建对象
student = Student()
#设置属性 替换原来的student.set_age(-18)
student.age=-18
#获取时不用写student.get_age()
print("年龄值:",student.age)

在这里插入图片描述
property() 小知识
使用 property()升级 setter 与 getter 方法,其实内部真实的处理方式是:①当“student.age = 29”执行时(即形式为:对象名.公有属性名=值),内部会自动调用 setter 方法;②当“print(“property()升级后年龄值为:%d”%student.age)”执行时(即形式为:对象名.公有属性名),内部会自动调用 getter 方法。
@property
装饰器

@...
def 方法名():
	代码

使用**@property可让setter与getter方法称为属性函数**,且可以对属性赋值时做必要的检查,并保证代码的简洁、清晰,它有两个主要作用(1)将 setter 与 getter 方法转换为只读方法;(2)重新实现一个属性的 setter 设置和 getter 读取方法,同时也可做为一个方法是否结束的判定,语法:

@property
def 方法名(self):
	return ...
@方法名.setter
def 方法名(self,value):
	...

注意,上述的语法格式中,方法名全部相同,在调用时,会把方法名当成一个共有属性名来调用

对象名.属性名 =#注:属性名即为上述的方法名
# coding:utf-8
class Student(object):
    def __init__(self):
        self.__age = 0

    @property
    def age(self): #稍后调用age age是共有属性名
        return self.__age
    @age.setter
    def age(self, value):  
        # if 0 <= age and age <= 140:
        if 0 <= value <= 140:
            self.__age = value
        else:
            self.__age = 0

# 使用 :创建对象
student = Student()
#设置属性
student.age=-18
print("年龄值:",student.age)

通过使用property后,可以命名相同的方法名,且调用时,会把该方法名当成是一个公有的属性名来使用。
动态语言
–静态语言(编译,再运行。C 语言、Java)、动态语言(在运行过程中,可以动态的添加属性、方法 --PHP、js、Python)
1.基本定义
动态语言的全称为"动态编程语言",这是高级程序设计语言的一个类别,已广泛应用于计算机科学领域。它是一类在程序执行时能够改变其结构的语言,如新的函数、属性,甚至能够引进新代码,同时已有的函数也能够被删除或有其他结构上的变化等。现如今,动态语言活跃于各类网站、博客、商业领域等,非常具有活力。例如,脚本语言 JavaScript(简称 JS)便是非常常见的一个动态语言–添加 table 表格 tr/tb,此外Python、PHP、Ruby等都属于动态语言,而开发者所熟知的 Java、C、C++等则不属于动态语言且是属于静态语言。
开始:java 源代码(.java 文件),使用 javac 命令进行
编译(编译源文件)
,形成一个.class 文件,使用 java 命令运行(已编译成功的文件)。
通俗地说,动态语言其实可以理解为不需编译即可运行,且在运行过程中能动态的添加属性、方法等,而像Java、C、C++等语言,都需要先进行编译,只有编译成功后,才能运行,而运行过程中是不允许动态的对已编译好的属性、方法等进行随意修改或添加新属性、新方法。
2.添加属性
1.给对象添加属性

# coding:utf-8
class User(object):
    #初始化属性
    def __init__(self,name,age):
        self.name=name
        self.age=age

user=User("小明",18)
print(user.name)
#给对象添加属性
user.sex="男"
print("性别:",user.sex)

在这里插入图片描述
可以发现,User类中没有sex属性,但却可以在运行过程中动态的添加sex属性且能访问到,这既可以说是动态语言的一个魅力,也可以说是一个坑吧。这其实就是在动态地给实例添加属性内容。
2.给类添加属性

user2=User("王刚",16)
print(user2.sex)

在这里插入图片描述
从上边报错可以看出,User类中没有sex这个属性,user对象添加了sex属性,现在调用的是user2,user对象的sex属性对user2不起作用。
若要给User实例对象都加上sex属性,语法格式:

类名.新属性名 = 属性值
class User(object):
    #初始化属性
    def __init__(self,name,age):
        self.name=name
        self.age=age


#给类添加属性
User.sex="男"
#创建对象1
user1=User("小亮",22)
print(user1.sex)
user2=User("小刚",22)
print(user1.sex)

在这里插入图片描述
需要注意的是,若在调用新属性且没设置新的属性值时,则使用默认值;若在调用新属性且已设置新的属性值时,则使用已设置的值

3.添加方法
1.普通方法

# coding:utf-8
def show(self):
    print("----普通方法----")

class User(object):
    def start(self):
        print("User类中的普通方法")
user=User()
user.start()
#添加
user.run=show
user.run()

在这里插入图片描述
run()方法不属于类或user对象,因此报错,若要解决,需要将run()方法添加到类User或user对象中。
在这里插入图片描述

# coding:utf-8
import types


def show(self):
    print("----普通方法----")

class User(object):
    def start(self):
        print("User类中的普通方法")
user=User()
user.start()
#添加方法 添加到user对象中的方法名为run
user.run=types.MethodType(show,user)
#调用
user.run()

在这里插入图片描述
2.静态方法和类方法
对于 Python 中的静态方法(@staticmethod)与类方法(声明 @classmethod),则可以直接采用如下语法格式:

类名.方法名 = 静态方法名或类方法名

此外,还需注意的是,要定义静态方法时,需要使用@staticmethod 声明;要定义类方法时,需要使用@classmethod 声明。

# coding:utf-8
@staticmethod
def run():
    print("静态方法 run()")

class User(object):
    def start(self):
        print("User类中的普通方法")
user=User()
user.start()
#添加方法 类名.方法名
User.run=run
#调用 
User.run()
#对象名调用
user.run()

在这里插入图片描述
类方法:注意第一个参数是cls

# coding:utf-8
@classmethod
def run(cls):
    print("类方法 run()")

class User(object):
    def start(self):
        print("User类中的普通方法")
user2=User()
user2.start()
#添加方法 类名.方法名
User.run=run
#调用
User.run()
#调用
user2.run()

在这里插入图片描述
相比于类似于 Python 的这类动态语言,静态语言更加严谨,下面来通俗的了解一下动态语言与静态语言的特性,如下:
1.动态语言:可以在程序运行过程中,动态的修改代码;
2.静态语言:首先要进行编译,在进行运行,当编译完成后就已确定好代码,在运行过程中不能随意修改代码。
若想要限制 Python 类能添加的属性,即限定外部只能动态的添加某些属性,此时就可以使用一个特殊的变量,那就是__slots__,该变量是一个元组(tuple)类型。
语法格式如下:–>在类中的第一个代码中,添加__slots__变量

__slots__ = ("属性名 1","属性名 2","属性名 3",...)
# coding:utf-8
class User(object):
    #限定User只能添加name,age
    __slots__ = ("name","age")
user=User()
user.name="小明"
user.age=18
user.sex="male"

在这里插入图片描述
3.删除属性
对于python动态语言的特性,也是可以删除属性的

del 对象名.属性名 #方式 1
delattr(对象名,"属性名") #方式 2 attribute
# coding:utf-8
class User(object):
    def __init__(self):
        self.name="小明"
        self.age=18

user=User()
print(user.name)
print(user.age)
print("--------------")
#删除属性
# del user.name
delattr(user,"name")
print(user.age)
print(user.name)

在这里插入图片描述
生成器
在之前的学习过程中,我们了解到,通过列表生成式**(list)可以直接创建一个列表变量**(列表元素 1000 万)。但是,受到不同电脑硬件的限制(如:内存容量不足),列表容量通常是有限个的。而实际应用中,当创建了一个包含100 万个元素的列表时,不仅占用很大的存储空间,若仅仅只需要访问前几个元素,则后面绝大多数元素内容所占用的空间都极大的浪费了内存资源。
因此,若列表元素可以按照某种算法进行推算出来,那是否可以在循环过程中不断推算出后续的元素内容呢?此时,则不必要创建出完整的 list,从而大大节省内存空间。在 Python 中,这种一边循环一边计算的算法机制,就称为生成器(generator)
1.创建生成器

# coding:utf-8
#列表推导式
lists=[x for x in range(5)]
print(lists)
#生成器
b=(x for x in range(5))
print(b)

在这里插入图片描述2.使用函数实现
生成器(generator)功能非常强大,若推算的算法较为复杂,且使用 for 循环(斐波那契数列–递归)无法实现时,
还可使用函数来进行实现。比如,数学中特别著名的斐波那契数列(Fibonacci),除第一个数和第二个数外,任意数都由前两个数相加求和所得到的,数列如下:
0,1, 1, 2, 3, 5, 8, 13, 21, 34, …

# coding:utf-8
def feibo(a):
    if a<=1:

        return a
    else:
		#递归算法
        return feibo(a-1)+feibo(a-2)
c=input("输入要输出几个斐波那契数列:")
lisa=[]
for i in range(int(c)):
    lisa.append(feibo(i))
print(lisa)
#斐波那契数列求和
print(sum(lisa))

在这里插入图片描述
还可以写成:

# coding:utf-8
def feibo(n):
    a = 0
    b = 1
    i = 0
    alist=[]
    while i < n:
        print(b)
        alist.append(b)
		#斐波那契数列规则 1+1 2 1+2 3 2+3 5
        a,b=b,a+b
        i+=1
    print(alist)
#生成器
feibo(6)

在这里插入图片描述
函数实际上定义了斐波那契数列的推算规则,可以从第一个元素开始,推算出后续任意的元素,这种四维其实非常类似于生成器(generator),而要把feibo函数编程生成器,只需要把上述程序稍加修改,将print(b)改为yield b即可

def feibo(n):
    a = 0
    b = 1
    # 循环
    i = 0
    while i < n:
        yield b
        # 斐波那契数列规则 1+1 2 1+2 3 2+3 5
        a, b = b, a + b
        i += 1


# 生成器
print(feibo(6))

结果
在这里插入图片描述
3.访问生成器元素

data=[x for x in range(5)]
print(data)

在这里插入图片描述

data=(x for x in range(5))
print(data)

在这里插入图片描述
区别在于最外层的[] () 中括号出来的是列表list,小括号是一个生成器(generator),直接打印生成器对象data,会发现打印出来的是generator类型与内存地址值,若需要打印元素值,可以使用next()函数
next(x) ---------获得 x 中的元素值,从初始元素开始依次获得,参数 x 表示生成器对象。
next(x) ---------获得 x 中的元素值,从初始元素开始依次获得,参数 x 表示生成器对象。

data=(x for x in range(5))
print(data)
try:
    print("第1个元素:",next(data))
    #print("第 1 个元素:", data.__next__())  
    print("第2个元素:",next(data))
    #print("第 2 个元素:", data.__next__())
    print("第3个元素:",next(data))
    print("第4个元素:",next(data))
    print("第5个元素:",next(data)) #取值完毕 下标越界 迭代(循环 遍历)
    print("第6个元素:",next(data))
    print("第7个元素:",next(data))
except Exception as error:
    print("StopIteration")

在这里插入图片描述
上述案例的斐波那契数列:

# coding:utf-8
def feibo(n):
    a = 0
    b = 1
    # 循环
    i = 0
    while i < n:
        yield b
        # 斐波那契数列规则 1+1 2 1+2 3 2+3 5
        a, b = b, a + b
        i += 1


# 生成器
print(feibo(6))
#生成器可以遍历输出值
for temp in feibo(6):
    print(temp)

在这里插入图片描述
4.send()函数

# coding:utf-8
#使用while循环获得0-10之间的自然数
def loop(number):
    i=0
    while i < number:
        print(i)
        i+=1
print(loop(10))

在这里插入图片描述
send(s)-----用于设置 yield 后的返回值内容。–返回值内容就是 s
一般地,next(x)等同于 send(None);对于上述案例,temp 用于接收下次 data.send(“hello”)发送过来的值

# coding:utf-8
#使用while循环获得0-10之间的自然数
def loop(number):
    i=0
    while i < number:
        # print(i)  #存储到一个算法中
        temp=yield i  #把这个内容保存在一个变量中,输出变量
        print("临时变量:",temp)
        i+=1
# print(loop(10))
#变量
datas=loop(10)
#获取元素用next()
print("第1个元素:",next(datas))
#默认调用send(None)
datas.send("hello")
print("第2个元素:",next(datas))

在这里插入图片描述
对于生成器,在这里,还需要注意:
(1)生成器是一个能记住上一次返回时在函数体中具体位置的函数;–算法
(2)使用生成器可节约内存资源,不至于大大浪费内存空间;–所有数据存在了一套算法中,若要获取数据元素,则可以通过算法快速获得 next()、next()
(3)对生成器遍历到下一次的调用(如:next())时,所使用的参数都是第 1 次调用时所留下的,即是在整个所有函数调用的参数都是第 1 次所调用时留下的,而不是重新创建的。


版权声明:本文为weixin_44897787原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。