python 基础 day8

pickle.load:切记,如果写入文件的是类,一定要先导入相关的类

一、上节回顾补充

二、面向对象(下) 成员

  1、字段 2、方法 3、属性

三、成员修饰符

四、特殊成员

五、面向对象边缘

六、异常处理

七、设计模式之单例模式

一、上节回顾补充

  面向对象基本知识:

    1、类和对象的关系

    2、三大特性: 封装、继承、多态(多种形态、多种类型)

多态

def func(arg):        #python中不用指定参数arg类型
    print(arg)
func(1)               #可以三数字
func("alex")          #可以三字符串
func([11,22,33,])     #可以三列表

在C#/java中 必须制定参数类型,下面用python的方式举例:

def func(A arg): #必须指定类型
    print(arg)

func(123)
func("alex") #报错(如果不是int类型就报错)

class A:
    pass
class B(A):
    pass
class C(A):
    pass
#arg 参数:必须是A类型或A的派生类类型
def func(A arg): #这里必须指定父类A,但arg的类型的类型可以三A、B、C
    print(arg)

二、面向对象中 成员

字段:

  静态字段、普通字段

ps:静态字段在代码加载时已经创建

class foo:
    #字段(静态字段)属于类,用类调用
    cc = 123

    def __init__(self):
        #字段(普通的字段)保存在对象里,用对象调用
        self.name = ‘alex‘  #如果没有创建对象,那么内存里就没有普通字段

一般情况:自己访问自己的字段

class Province:
    country = "中国"

    def __init__(self,name):
        self.name = name

hn = Province("河南")
hb = Province("河北")
print(hn.name)  # 在对象里用对象访问
print(Province.country)  # 在类里用类访问
# 在Python里也可以用对象访问静态字段
print(hn.country)

规则:
    普通字段只能用对象访问
    静态字段用类访问(万不得已不要用对象访问)

方法: 所有方法属于类(在其他语言里只有两种方法

1、普通方法:至少一个self,对象执行

2、静态方法:任意参数,没有self,类执行

3、类方法:至少有一个cls参数,由类执行

class Province:
    country = "中国"

    def __init__(self,name):
        self.name = name
    #普通方法,由对象去调用执行(方法属于类)
    def show(self):
        print(self.name)

    #静态方法,由类调用执行(操作1、2、之后变成静态方法)
    @staticmethod #2、加上@staticmethod
    def f1(): #1、参数里去掉self,可以有其他参数
        print("....")

    #类方法(静态方法的一种)
    @classmethod
    def f2(cls): #至少必须有一个参数cls,自动传递参数返回类名
        #cls #类名,()创建对象
        #cls()
        print(cls) #类名<class ‘__main__.Province‘>

    def f3(self):
        return self.name[1]

obj = Province("河南")
obj.show()
Province.f1()
Province.f2()  #<class ‘__main__.Province‘>
ret = obj.f3()
print(ret)     #南 

属性

  不伦不类的东西

  具有方法的写作形式,具有字段的访问形式

class Page:
    def __init__(self,all_count):
        self.all_count = all_count

    @property   #属性就需要加上property这个方法
    def all_pager(self):
        a1,a2 = divmod(self.all_count,10)
        if a2 == 0:
            return  a1
        else:
            return a1 + 1

    @all_pager.setter  #函数名.setter ,设置
    def all_pager(self,value):      #函数名都和上一个相同
        print(value)

    @all_pager.deleter  # 删除
    def all_pager(self):
        print("del")

#all_pager没有加上属性之前,用下面形式操作
#p = Page(101)
# r = p.all_count #字段
# result = p.all_pager() #方法
# print(result)

#all_pager加上属性之后
p.all_count = 102
del p.all_count  #删除方法的字段
ret = p.all_pager #属性 (属性和方法区别就是少了括号)
print(ret)

p.all_pager = 111 #用属性重新定义
del p.all_pager  #用属性删除,伪删除动作,里面执行什么自己定义的

另一种属性

class Pager:
    def __init__(self,all_count):
        self.all_count = all_count

    def f1(self):
        return "f1"

    def f2(self,value):
        print(value)

    def f3(self):
        print("f3")

    foo = property(fget=f1,fset=f2,fdel=f3) #还可以按顺序直接给值

p = Pager(101)
ret = p.foo
print(ret)

obj = Pager(110)
obj.foo = "f2"

del obj.foo

#结果
f1
f2
f3

三、成员修饰符

  私有的: 只能类自己本身的成员访问调用,其他类不能访问

  公有的: pass

class Foo:
    def __init__(self,name,age):
        self.__name = name #加两个下划线,只能在类的内部访问,外部访问不到
        self.age = age

    def f1(self):
        print(self.__name)

class Bar(Foo):
    def f2(self):
        print(self.age)  #这里如果写成self.__name则外面获取obj1.f2()会报错

obj = Foo("alex",13)
#print(obj.__name)  #会报错,外部不能访问

obj1 = Bar("Q",12)
obj1.f2()   #继承也不能执行__name,只能本身类内部访问
obj1.f1()#print(obj._Foo__name) #(可以取到私有的,不到万不得已不要强制访问)

四、特殊成员

构造方法 __init__
析构方法 __del__  :垃圾清除之前自动执行 类的__del__方法(有就执行没有不执行)

__call__ :对象加括号,就会自动执行__call__方法

__str__:直接打印对象,就会自动执行__str__方法

__getitem__:获取

__setitem__:设置

__delitem__:删除

class F:
    #构造方法
    def __init__(self,name,age):
        self.name =name
        self.age =age
    #析构方法
    def __del__(self):
        pass

    def __call__(self, *args, **kwargs):
        print("123")

    def __str__(self):
        return "%s" % self.name

    def __getitem__(self, item):
        # print(item.start)#obj[1:2] 中的1
        # print(item.stop)#2
        # print(item.step) #步长
        return "getitem"

    def __setitem__(self, key, value):
        #key.star key.stop key.step
        return "setitem"

    def __delitem__(self, key):
        # key.star key.stop key.step
        print("del item")
p = F("QL",12)
print(p.__class__) #<class ‘__main__.F‘>

obj = F("QL",15)
#语法对应关系
ret = obj["ad"] # 自动执行getitem方法,自动赋值给item
ret1 = obj[1:2] #切片 会执行getitem方法
print(ret1)
obj[1:4] = [11,22,33,44,55,66,] #自动执行setitem方法
del obj[1:3] #自动执行 delitem
print(obj) #直接打印对象,就会自动执行__str__方法
obj()   #对象加括号,就会自动执行__call__方法
# #ret = obj["k1"] = 111 #自动执行setitem方法
# #print(ret)
#
# del obj["k1"]  #自动执行delitem方法

obj() #加上__call__方法才能执行(对象后加括号)

#F()() #也可以写成这样

print(obj) #不加str会输出内存地址<__main__.F object at 0x0000000000726630>,加上__str__会友好显示,str里返回什么就输出什么

#__dict__ #获取对象中封装的数据 【重要】
ret = obj.__dict__
print(ret) #{‘age‘: 12, ‘name‘: ‘QL‘}

#print(F.__dict__)#获取类中的成员

__iter__

class F1():
    def __iter__(self): #iter是生成器(里面有yield就是生成器)
        #yield 1
        #yield 2
        return iter([11, 22, 33, ])

obj = F1()
for item in obj:#默认不可以迭代,加上iter方法才可以迭代
    print(item)#默认执行iter方法,迭代iter返回值

五、面向对象边缘

  - insinstance 查看某个对象是不是某个类创建的

  - issubclass 查看某个类是不是某个类的子类

class A:
    pass

class B(A):
    pass

obj = A()
ret = isinstance(obj,B)

class Bar:
    pass

class Foo(Bar):
    pass

obj = Foo()
#obj,Bar(obj类型和obj类型的父类)的实例
ret2 = isinstance(obj,Bar) #查看obj是不是Bar创建的
print(ret2) #True
ret1 = issubclass(Bar,Foo)# 查看Bar 是不是Foo的子类
print(ret1) #False

主动执行父类方法:

class C1:

    def f1(self):
        print("c1.f1")

class C2(C1):

    def f1(self):
        # # 主动执行父类的f1方法
        super(C2,self).f1()
        print("c2.f1")

        #C1.f1(self) #不建议使用,用上面的super方法

obj1 = C2()
obj1.f1()

有序字典

class MyDict(dict):

    def __init__(self):
        self.li = []
        super(MyDict, self).__init__()

    def __setitem__(self, key, value):
        self.li.append(key)
        super(MyDict, self).__setitem__(key,value)

    def __str__(self):
        temp_list = []
        for key in self.li:
            value = self.get(key)
            temp_list.append("‘%s‘:%s"% (key,value))
        temp_str = "{" + ",".join(temp_list) + "}"
        return  temp_str
obj = MyDict()
obj["k1"] = 123
obj["k2"] = 456
print(obj) #继承父类的setter
#结果
{‘k1‘: 123, ‘k2‘: 456}

六、异常处理

while True:
    num1 = input(‘num1:‘)
    num2 = input(‘num2:‘)
    try:
        li = [11, 22]
        print(‘li[100]‘) #indexerro
        num1 = int(num1)
        num2 = int(num2)
        result = num1 + num2

    except ValueError as ex:  #只捕获ValueError错误 从上往下捕获
        print(‘ex‘)
    except IndexError as ex:
        print(‘ex‘)
    except Exception as ex:  # ex 是Exception的一个对象,Exception捕获所有错误
        print(‘ex‘)  # str

完整代码块

try:
    pass
except ValueError as ex:
    print(ex)
except Exception as ex:
    print(ex)
else:  #上面不报错执行else
    pass
finally: #不管报不报错都执行finally
    pass

主动触发异常

try:
    raise Exception(‘主动错误一下‘) #self.message = ‘主动错误一下’
    print(1234)
except ValueError as ex:
    print(ex)
except Exception as ex:#__str__,return self.message
    print(ex)
else:  #上面不报错执行else
    pass
finally: #不管报不报错都执行finally
    pass

断言

assert 1==1 #如果条件成立不报错

assert 1==2 #如果条件不成立报错

p = obj()
p.start() #在执行start之前先执行一个 p.status == False,就可以在start中写入(assert p.staus == False)

七、设计模式之单例模式(23种,推荐书《goF设计模式》)

  单例模式: 用来创建单个实例

class Foo:

    instance = None

    def __init__(self,name):
        self.name = name
    @classmethod
    def get_instance(cls):
        #cls 类名
        if cls.instance:
            return  cls.instance
        else:
            obj = cls("alex") #一般是固定值,也可以传参
            cls.instance = obj #对象赋值给instance
            return obj
obj1 = Foo.get_instance()
print(obj1)
obj2 = Foo.get_instance()
print(obj2)

谁来访问都创建一个,比较浪费,不如只创建一个,都来访问这一个。

时间: 2024-11-13 14:24:37

python 基础 day8的相关文章

Python基础day-8[装饰器补充,迭代器(未完)]

wraps模块: 让函数保留原来的说明信息. 在闭包函数上面 @wraps 可以把原代码的解释,引用到装饰器中,让用户彻底无法感知装饰器的存在 使用 func.__doc__ 和 print(help(func))来查看函数的注释信息 from functools import wraps import time def coutime(func): @wraps(func) #调用wraps模块 def wrapper(*args,**kwargs): # 'a1231231231231232

linux+jmeter+python基础+抓包拦截

LINUX 一 配置jdk 环境 *需要获取root权限,或者切换为root用户 1.windows下载好,去 http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 官方网站下载jdk(linux相应版本) 2.在usr目录下创建java路径文件夹 [root bin]cd /usr mkdir java 3.将jdk-8u60-linux-x64.tar.gz放到刚才创建的文件夹下

Python基础教程(第九章 魔法方法、属性和迭代器)

本文内容全部出自<Python基础教程>第二版,在此分享自己的学习之路. ______欢迎转载:http://www.cnblogs.com/Marlowes/p/5437223.html______ Created on Marlowes 在Python中,有的名称会在前面和后面都加上两个下划线,这种写法很特别.前面几章中已经出现过一些这样的名称(如__future__),这种拼写表示名字有特殊含义,所以绝不要在自己的程序中使用这样的名字.在Python中,由这些名字组成的集合所包含的方法称

Python基础入门 (一)

一.关于版本的选择 Should i use Python 2 or Python 3 for my development activity?转载自Python官网 Short version: Python 2.x is legacy, Python 3.x is the present and future of the language Python 3.0 was released in 2008. The final 2.x version 2.7 release came out

Python 基础 - Day 4 Learning Note - Generator 生成器

列表生成器/列表解析 list comprehension 简单灵活地创建列表,通常和lambda(), map(), filter() 一起使用 通过列表生成式, 直接创建列表.但是,收到内容限制,列表容量肯定是有限的.而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问几个元素,那其他的就白占空间.列表生成器能够一边循环一边计算,大大节省大量的空间.是生成器的一种. 只有调用,才能生成. 不支持切片操作,只能通过__next()___一个个取数字. 基本语法

python基础教程(第二版)

开始学习python,根据Python基础教程,把里面相关的基础章节写成对应的.py文件 下面是github上的链接 python基础第1章基础 python基础第2章序列和元组 python基础第3章使用字符串 python基础第4章字典 python基础第5章循环 python基础第6章函数和魔法参数 python基础第7章类 python基础第8章异常 python基础第9章魔法方法.属性和迭代器 python基础第11章文件 python基础第12章GUI(wxPython) pytho

python基础周作业

python基础周作业 1.执行python脚本的两种方法 脚本前面直接指定解释器 在脚本开始前声明解释器 2.简述位,字节的关系 每一个字节占用八个比特位 3, 简述ascii.unicode.utf- ‐8.gbk的关系 utf--‐8 <-- unicode <-- gbk <-- ascii 按此方向兼容 4..请写出"李杰"分别用utf- ‐8和gbk编码所占的位数 "李杰" 占用utf -8 占6字节 , gbk 占用4字节 5.pyt

Python基础(二)

Python基础(二) Python 运算符(算术运算.比较运算.赋值运算.逻辑运算.成员运算) 基本数据类型(数字.布尔值.字符串.列表.元组.字典.set集合) for 循环 enumrate range和xrange 编码与进制转换 Python 运算符 1.算术运算: 2.比较运算: 3.赋值运算: 4.逻辑运算:  5.成员运算: 基本数据类型 1.数字 int(整型) 在32位机器上,整数的位数为32位,取值范围为-2**31-2**31-1,即-2147483648-2147483

Python之路【第三篇】:Python基础(二)

Python之路[第三篇]:Python基础(二) 内置函数 一 详细见python文档,猛击这里 文件操作 操作文件时,一般需要经历如下步骤: 打开文件 操作文件 一.打开文件 1 文件句柄 = file('文件路径', '模式') 注:python中打开文件有两种方式,即:open(...) 和  file(...) ,本质上前者在内部会调用后者来进行文件操作,推荐使用 open. 打开文件时,需要指定文件路径和以何等方式打开文件,打开后,即可获取该文件句柄,日后通过此文件句柄对该文件操作.