python中级13面向对象模块

1 属性和方法

●属性
----类属性,直接在类中定义的属性是类属性
----类属性可以通过类或类的实例访问到。但是类属性只能通过类对象来修改,无法通过实例对象修改
----实例属性 通过实例对象添加的属性属于实例属性
----实例属性只能通过实例对象来访问和修改,类对象无法访问修改
●方法
----在类中定义,以self为第一个参数的方法都是实例方法
----实例方法在调用时 Python会将调用对象以self传入
----实例方法可以通过类实例和类去调用
----当通过实例调用时,会自动将当前调用对象作为self传入
----当通过类调用时,不会自动传递self,我们必须手动传递self
----类方法 在类的内容以@classmethod来修饰的方法属性类方法
----类方法第一个参数是cls也会自动被传递。cls就是当前的类对象
----类方法和实例方法的区别,实例方法的第一 个参数是self, 类方法的第一个参数是cls
----类方法可以通过类去调用,也可以通过实例调用
●静态方法
----在类中用@staticmethod来修饰的方法属于静态方法
----静态方法不需要指定任何的默认参数,静态方法可以通过类和实例调用
----静态方法,基本上是一个和当前类无关的方法,它只是一个保存到当前类
中的函数
----静态方法一般都是些工具方法,和当前类无关

类属性和实例属性

咱们先说说类属性和实例属性

class A(object):
    # 类属性 直接在类中定义的属性 (其实就是在类中创建了一个变量这么理解也可以)
    # 类属性可以通过可以通过类和该类的实例来访问
    count=0

a=A()
print(A.count) #通过类来访问类属性
print(a.count) #通过实例来访问类属性


0
0
class A(object):
  # 类属性 直接在类中定义的属性 (其实就是在类中创建了一个变量这么理解也可以)
    # 类属性可以通过可以通过类和该类的实例来访问
    # 类中的属性只能通过类对象来修改,无法通过实例对象来修改
    count=0

a=A()
a.count=10


print(A.count)
print(a.count)  #我们发现类中的属性没有改变 实例对象中的属性改变了
0
10				 # 类中的属性无法通过实例对象来修改
class A(object):

    count=0

a=A()

A.count=20

print(A.count)
print(a.count)  #我们发现类中的属性改变了 实例对象中的属性也改变了
				#如果实例找属性 如 count 会先在自己里 找 没有再去类对象中去找


20
20			

那么我们定义的__init__函数中的属性是类属性吗

class A(object):
    # 类属性 直接在类中定义的属性 (其实就是在类中创建了一个变量这么理解也可以)
    # 类属性可以通过可以通过类和该类的实例来访问
    # 类中的属性只能通过类对象来修改,无法通过实例对象来修改
    count=0

    def __init__(self):
        self.name='葫芦娃'

a=A()

#实例属性 通过实例对象来添加的属性就是实例属性
#a.count=10
# A.count=20

print(A.name)


AttributeError: type object 'A' has no attribute 'name'
属性错误:类型对象“A”没有属性“name”

class A(object):
    # 类属性 直接在类中定义的属性 (其实就是在类中创建了一个变量这么理解也可以)
    # 类属性可以通过可以通过类和该类的实例来访问
    # 类中的属性只能通过类对象来修改,无法通过实例对象来修改
    count=0

    def __init__(self):    #(这里特殊的实例属性)
        self.name='葫芦娃'   他在类里是确确实实的  但是它却是个实例属性 就是这个葫芦娃是实例属性 因为self 表示 当前对象添加的属性  其实他是添加到当前对象(实例对象)中了  

a=A()

#实例属性 通过实例对象来添加的属性就是实例属性
#a.count=10
# A.count=20


print(a.name)
葫芦娃

方法

实例方法

●方法
实例方法
----在类中定义,以self为第一个参数的方法都是实例方法
----实例方法在调用时 Python会将调用对象以self传入
----实例方法可以通过类实例和类去调用
----当通过实例调用时,会自动将当前调用对象作为self传入
----当通过类调用时,不会自动传递self,我们必须手动传递self (此处指的是实例 如a 若是直接传递self self 这个name没有被定义)

class A(object):

    count=0

    def __init__(self):

        self.name='葫芦娃'
    #实例方法
    #在类中定义 以self为第一个参数的方法都是实例方法
    #
    def text(self):   #这个self并不需要传递  谁调用就是谁 
        print('这是test方法')

a=A()


这是test方法
class A(object):

    count=0

    def __init__(self):

        self.name='葫芦娃'
    #实例方法
    #在类中定义 以self为第一个参数的方法都是实例方法
    #
    def text(self):   #这个self
        print('这是test方法',self)

a=A()

a.text()


这是test方法 <__main__.A object at 0x00000000020B3520>

试试A.text( )行不行

class A(object):

    count=0

    def __init__(self):

        self.name='葫芦娃'
    #实例方法
    #在类中定义 以self为第一个参数的方法都是实例方法
    #当通过实例对象调用时 会自动传递当前对象作为self传入
    #当通过类去调用时 不会自动传递self
    def text(self):   #这个self
        print('这是test方法')

a=A()

A.text()



TypeError: text() missing 1 required positional argument: 'self'
类型错误:text()缺少1个必需的位置参数:“self”
class A(object):

    count=0

    def __init__(self):

        self.name='葫芦娃'
    #实例方法
    #在类中定义 以self为第一个参数的方法都是实例方法
    #当通过实例对象调用时 会自动传递当前对象作为self传入
    #当通过类去调用时 不会自动传递self
    def text(self):   #这个self
        print('这是test方法')

a=A()

A.text(a)                     由此可以看出   a.text() 等价于 A.text(a)



这是test方法

类方法

----类方法 在类的内容以@classmethod来修饰的方法属性类方法
----类方法第一个参数是cls也会自动被传递。cls就是当前的类对象
----类方法和实例方法的区别,实例方法的第一 个参数是self, 类方法的第一个参数是cls
----类方法可以通过类去调用,也可以通过实例调用 (就是上述的用类调用实例方法是得加上 self (a) 而用实例调用类方法是什么都不用加的)

class A(object):

    count=0

    def __init__(self):

        self.name='葫芦娃'
    #实例方法
    #在类中定义 以self为第一个参数的方法都是实例方法
    #当通过实例对象调用时 会自动传递当前对象作为self传入
    #当通过类去调用时 不会自动传递self
    def text(self):   #这个self
        print('这是test方法',self)

    #类方法
    #在类的内部使用 @classmethod 来修饰的方法属于类方法
    #类方法的第一参数我们习惯写成cls 也会自动传递 clas就相当于当前的类对象
    @classmethod
    def test2(cls):
        print('这个是test2方法',cls)


a=A()  #a.text() 等价于 A.text(a)

A.test2()


这个是test2方法 <class '__main__.A'>
class A(object):

    count=0

    def __init__(self):

        self.name='葫芦娃'
    #实例方法
    #在类中定义 以self为第一个参数的方法都是实例方法
    #当通过实例对象调用时 会自动传递当前对象作为self传入
    #当通过类去调用时 不会自动传递self
    def text(self):   #这个self
        print('这是test方法',self)

    #类方法
    #在类的内部使用 @classmethod 来修饰的方法属于类方法
    #类方法的第一参数我们习惯写成cls 也会自动传递 clas就相当于当前的类对象
    @classmethod
    def test2(cls):
        print('这个是test2方法',cls)
        print(cls.count)  #也可以用cls 访问类属性

a=A()  #a.text() 等价于 A.text(a)

A.test2()


这个是test2方法 <class '__main__.A'>
0

类方法可以通过类去调用,也可以通过实例调用 (就是上述的用类调用实例方法是得加上 self (a) 而用实例调用类方法是什么都不用加的)

class A(object):

    count=0

    def __init__(self):

        self.name='葫芦娃'
    #实例方法
    #在类中定义 以self为第一个参数的方法都是实例方法
    #当通过实例对象调用时 会自动传递当前对象作为self传入
    #当通过类去调用时 不会自动传递self
    def text(self):   #这个self
        print('这是test方法',self)

    #类方法
    #在类的内部使用 @classmethod 来修饰的方法属于类方法
    #类方法的第一参数我们习惯写成cls 也会自动传递 clas就相当于当前的类对象
    @classmethod
    def test2(cls):
        print('这个是test2方法',cls)
        print(cls.count)

a=A()  #a.text() 等价于 A.text(a)

a.test2()



这个是test2方法 <class '__main__.A'>
0

静态方法

●静态方法
----在类中用@staticmethod来修饰的方法属于静态方法
----静态方法不需要指定任何的默认参数,静态方法可以通过类和实例调用
----静态方法,基本上是一个和当前类无关的方法,它只是一个保存到当前类
中的函数
----静态方法一般都是些工具方法,和当前类无关

咱们再试一下静态方法

class A(object):

    count=0

    def __init__(self):

        self.name='葫芦娃'
    #实例方法
    #在类中定义 以self为第一个参数的方法都是实例方法
    #当通过实例对象调用时 会自动传递当前对象作为self传入
    #当通过类去调用时 不会自动传递self
    def text(self):   #这个self
        print('这是test方法',self)

    #类方法
    #在类的内部使用 @classmethod 来修饰的方法属于类方法
    #类方法的第一参数我们习惯写成cls 也会自动传递 clas就相当于当前的类对象
    @classmethod
    def test2(cls):
        print('这个是test2方法',cls)
        print(cls.count)
    #静态
    #在类中使用  @staticmethod来修饰的方法我们称之为静态方法
    #不需要制定任何的默认参数 静态方法可以被类对象和实例对象调用
    #静态方法跟类本身无关 就是一个功能函数
    @staticmethod
    def test3():
        print('这是test3方法')



a=A()  #a.text() 等价于 A.text(a)

A.test3()




这是test3方法
class A(object):

    count=0

    def __init__(self):

        self.name='葫芦娃'
    #实例方法
    #在类中定义 以self为第一个参数的方法都是实例方法
    #当通过实例对象调用时 会自动传递当前对象作为self传入
    #当通过类去调用时 不会自动传递self
    def text(self):   #这个self
        print('这是test方法',self)

    #类方法
    #在类的内部使用 @classmethod 来修饰的方法属于类方法
    #类方法的第一参数我们习惯写成cls 也会自动传递 clas就相当于当前的类对象
    @classmethod
    def test2(cls):
        print('这个是test2方法',cls)
        print(cls.count)
    #静态
    #在类中使用  @staticmethod来修饰的方法我们称之为静态方法
    #不需要制定任何的默认参数 静态方法可以被类对象和实例对象调用
    #静态方法跟类本身无关 就是一个功能函数
    @staticmethod
    def test3():
        print('这是test3方法')



a=A()  #a.text() 等价于 A.text(a)

A.test3()



这是test3方法

就比如 我这里有个函数 放在全局里不好 放在哪都不好 这时候你希望有个地方去存的的时候 就可以给他整成一个静态方法

2 模块

–模块的简介–
模块化
●模块化指将一个完整的程序分解成一个个的小模块
●通过将模块组合,来搭建出一个完整的程序
●模块化的优点
----方便开发
----方便维护
----模块可以复用

3模块的创建

●在Python当中一个py文件就是一个模块
●在一个模块中引入外部模块 import 模块名(模块名就是py文件)
●可以引入同一个模块多次,但是模块的实例只会创建一次
●import 模块名 as 模块别名
●在一个模块内部都有一个__name__。通过它我们可以获取模块的名字
●如果py文件直接运行时,那么__name__默认等于字符串’main’。
__name__属性值为__main__的模块是主模块。一个程序中只有一个主模块
在这里插入图片描述
在这里插入图片描述
运行一下模块文件 结果是这是我的第一个模块
接着上面的操作

#在python 中一个py文件就是一个模块
#在一个模块中引入外部模块
#1 import 模块名(模块名就是python的文件名)
import test_m
import test_m
import test_m  #运行后

这是我的第一个模块

在这里插入图片描述
#在python 中一个py文件就是一个模块
#在一个模块中引入外部模块
#import 模块名(模块名就是python的文件名)
#可以引入同一个模块多次 但是模块只会执行一次


import test_m

print(test_m)



这是我的第一个模块
<module 'test_m' from 'D:\\LongProject\\test_m.py'>
module就是模块  模块tset_m 从D盘 LongProject夹 的test_m.py 这来的  (这就是一个模块名字指向的路径)

接下来说一个非常非常重要的东西
我们先在test_m.py 中 来个print(name)
在这里插入图片描述
我们再在 模块.py 中引入模块 test_m
运行一下后 应该是打印__name__
然而
在这里插入图片描述
name

模块就是test.py 模块.py 这些文件

在每一个模块中都有__name__ 我们可以用它来获取模块的名字
在这里插入图片描述
上面说的__name__ 我们可以用它来获取模块的名字
但是这里却是__main__
如果这个模块直接运行 那么__name__ 默认的字符串 main 表示当前文件为主文件


#如果这个模块直接运行 那么__name__ 默认的字符串 __main__ 表示当前文件为主文件

print(__name__)



__main__

4 模块的使用

●访问模块中的变量 语法是 模块名.变量名
●访问模块中的函数 语法是 模块名.函数名
●访问模块中的对象 语法是 模块名.对象名
●我们也可以引入模块中部分内容 语法 from 模块名 import 变量,变量…(第三种引入模块方法)
●还有一种引入方式 语法 from 模块名 import 变量 as 别名 (第二种)

第一种引入模块的方式

访问模块中的变量
在这里插入图片描述在这里插入图片描述
访问模块中的函数
在这里插入图片描述在这里插入图片描述
上图上面还有 一个import test_m

import test_m



#访问模块中的函数 语法是 模块名.函数名


test_m.test1()      #比较像 import requests
                    #      requests.get()    这个形式
test_m.test2()



test1
test2

●访问模块中的对象 语法是 模块名.对象名
类也是对象
在模块中定义类
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

再把print(p.name) 注释掉
在这里插入图片描述
在这里插入图片描述

第二种引入模块的方式

第二种引入模块方法 2 import 模块名 as 模块别名
在这里插入图片描述
在这里插入图片描述
模块.py 中

#2 import 模块名 as 模块别名
import test_m as test
print(test_m)

NameError: name 'test_m' is not defined
#2 import 模块名 as 模块别名
import test_m as test
print(test)

这是我的第一个模块
<module 'test_m' from 'D:\\LongProject\\test_m.py'>

第三种引入模块的方式

第三种引入模块方法
#第3种语法 from 模块名 import 变量
test_m 测试模块中
在这里插入图片描述
在这里插入图片描述
由上我们可以看出 以第三种方式是无法打印出test_m 这个对象的
在这里插入图片描述
在test_m 测试模块中的前提上
在这里插入图片描述
#第3种语法 from 模块名 import 变量,变量,变量
在这里插入图片描述
#3 语法 from 模块名 import 变量,变量,变量
在这里插入图片描述

第四种引入模块的方式

#第4种 语法: from 模块名 import *

依然是在模块test_m (测试模块)基础上

在这里插入图片描述

在这里插入图片描述
当然第四种方法没有第一种保险
比如我们在主模块 中

def test1():

print('主模块中的test1')

在这里插入图片描述
由上图可看出 test1()调用的是 测试模块的 test()函数 而非 主模块的
在这里插入图片描述
在这里插入图片描述
由上可得出在引入模块后再定义函数 你再 调用函数那都是主模块的函数(灰色)
引入模块是灰色的 那他就没被引入

方法一与方法二的区别
在这里插入图片描述
在这里插入图片描述
就算主模块也定义有函数test1() (当然前提是不在引入模块后定义的)第三种方式还是会去调用测试模块的函数 而 第一种与之相反

第五种引入模块的方式

#5 语法:from 模块名 import 变量 as 别名

就是你的主模块和你的测试模块出现相同名称的函数的时候
那么我们可以给他起一个别名
在这里插入图片描述

在这里插入图片描述
意思就是给测试模块 test_m 中的 test1()函数起了新名字 new_test1

在测试模块 test_m 中 加入私有变量c=3
在这里插入图片描述
在这里插入图片描述
咱们之前学封装可以_c=3
在这里插入图片描述
在这里插入图片描述
##我们再尝试一个
在测试模块中
在这里插入图片描述
在主模块中运行.
在这里插入图片描述
然后你就发现了测试模块中的测试代码也打印 了

我们写的测试代码是为了测试模块没什么问题 而在主模块一引用 测试代码在主模块又执行了
所以我们希望编写测试 或者我们编写一部分代码 只在当前文件为主文件时可以执行 而其他模块 在引入这个模块时 就不要在执行了 (此问题前面也出现过 但未强调)
所以我们可以做一个判断来解决此问题


#
# #在模块中定义变量
a=1
b=2
#c是私有的(不希望你去修改)
_c=3
#
#
# # 在模块中定义函数
def test1():
    print('test1')

def test2():
    print('test2')

# # 在模块中定义类

class Person():
    def __init__(self):
        self.name='葫芦娃'
p=Person()

if __name__ =='__main__':
    #以下是测试代码
    print(p.name)
    test1()
    test2()

在这里插入图片描述
所以主模块中就不再发生类似的尴尬
在这里插入图片描述

迭代器和生成器

迭代器

#迭代器 访问元素的一种方式 (遍历也是一种访问元素的一种方式)
#特点是可以记住遍历位置的对象
#迭代器也是从序列当中第一个元素访问 直到所有的元素被访问完结束(而且迭代器是只会往前不会后退)
#iter() next() (其实整个迭代器都是围绕这两个方法的)


#迭代器  访问元素的一种方式 (遍历也是一种访问元素的一种方式)
#特点是可以记住遍历位置的对象
#迭代器也是从序列当中第一个元素访问 直到所有的元素被访问完结束(而且迭代器是只会往前不会后退)
#iter() next()  (其实整个迭代器都是围绕这两个方法的)



lst=[1,2,3,4,5,6,7]

myiter=iter(lst)

print(next(myiter))


1
lst=[1,2,3,4,5,6,7]

myiter=iter(lst)

print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))


1
2
3
4
5
6
7               你在来个print(next(myiter)) 就会报错 StopIteration  
													停止迭代

但是这样写太多重复代码了
我们经常用的方法是

lst=[1,2,3,4,5,6,7]

myiter=iter(lst)

for i in myiter:    # 迭代数据结构
    print(i)

1
2
3
4
5
6
7

生成器

#生成器 在Python 中使用yield 这个关键字 我们就称之为生成器或者生成器函数
#生成器和普通函数的区别 返回的是一个迭代器的函数 只用于迭代器作业 (可以简单的理解生成器就是一个特殊的迭代器)
#next() 方法 当前位置继续访问


def fn():
    print('11')
    yield 1
    print('12')
    yield 2
    print('13')
    yield 3
    print('14')
    yield 4
    print('15')
    yield 5

print(type(fn))  #<class 'function'>

f=fn()

print(type(f))


<class 'function'>
<class 'generator'>   generator就是生成器的意思
def fn():
    print('11')
    yield 1
    print('12')
    yield 2
    print('13')
    yield 3
    print('14')
    yield 4
    print('15')
    yield 5

# print(type(fn))  #<class 'function'>

f=fn()

# print(type(f))#<class 'generator'>

next(f)

11
def fn():
    print('11')
    yield 1
    print('12')
    yield 2
    print('13')
    yield 3
    print('14')
    yield 4
    print('15')
    yield 5

# print(type(fn))  #<class 'function'>

f=fn()

# print(type(f))#<class 'generator'>
# next(f)# 11
print('返回:',next(f))


11                  可以看出先是打印11  再返回
返回: 1
def fn():
    print('11')
    yield 1
    print('12')
    yield 2
    print('13')
    yield 3
    print('14')
    yield 4
    print('15')
    yield 5

# print(type(fn))  #<class 'function'>

f=fn()

# print(type(f))#<class 'generator'>
# next(f)# 11
print('返回:',next(f))# 11 返回:1
print('返回:',next(f))# 12 返回:2
print('返回:',next(f))# 13 返回:3



11
返回: 1
12
返回: 2
13
返回: 3

yied 也是在返回值 但是它跟return 不太一样 return 是返回后下面的代码都不会在执行
(这算是一个拓展的内容)

最后环节复习

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值