面向对象

特殊成员

class Foo(object):

 

    def __init__(self,a1,a2):

        self.a1 = a1

        self.a2 = a2

   

    def __call__(self, *args, **kwargs):

        print(11111,args,kwargs)

        return 123

 

    def __getitem__(self, item):

        print(item)

        return 8

 

    def __setitem__(self, key, value):

        print(key,value,111111111)

 

    def __delitem__(self, key):

        print(key)

 

    def __add__(self, other): 对象相加

        return self.a1 + other.a2

 

    def __enter__(self):  和下面exit成对出现

        print('1111')

        return 999

 

    def __exit__(self, exc_type, exc_val, exc_tb):

        print('22222')

 

# 1. 类名() 自动执行 __init__

# obj = Foo(1,2)

 

# 2. 对象() 自动执行 __call__

# ret = obj(6,4,2,k1=456)

 

# 3. 对象['xx']  自动执行 __getitem__

# ret = obj['yu']

# print(ret)

 

# 4. 对象['xx'] = 11  自动执行 __setitem__

# obj['k1'] = 123

 

# 5. del 对象[xx]     自动执行 __delitem__

# del obj['uuu']

 

# 6. 对象+对象         自动执行 __add__

# obj1 = Foo(1,2)

# obj2 = Foo(88,99)

# ret = obj2 + obj1

# print(ret)

 

# 7. with 对象        自动执行 __enter__ / __exit__

# obj = Foo(1,2)

# with obj as f:

#     print(f)

#     print('内部代码')

 

# 8. 真正的构造方法

# class Foo(object):

#     def __init__(self, a1, a2):     # 初始化方法

#         """

#         为空对象进行数据初始化

#         :param a1:

#         :param a2:

#         """

#         self.a1 = a1

#         self.a2 = a2

#

#     def __new__(cls, *args, **kwargs): # 构造方法

#         """

#         创建一个空对象

#         :param args:

#         :param kwargs:

#         :return:

#         """

#         return object.__new__(cls) # Python内部创建一个当前类的对象(初创时内部是空的.).

#

# obj1 = Foo(1,2)

# print(obj1)

#

# obj2 = Foo(11,12)

# print(obj2)

 

 

 

day25

特殊方法补充


# __str__

class F1(object):

    def __init__(self):
        pass
    def func(self):
        pass

    # 当加了__str__,返回的不再是对象的内存地址,而是str中返回的内容
    def __str__(self):
        return 'F1类'
obj = F1()

print(obj)   # <__main__.F1 object at 0x0000018D3F823470> ,返回内存地址
print(obj)   # F1类 ,当添加了str方法就打印的是返回值


# __doc__
class F1(object):
    '''
    
这里是F1类
    '''
    
def __init__(self):
        pass
    def func(self):
        pass

obj = F1()
print(obj.__doc__) # 打印类最前面的注释,将注释放在下面就打印为None

# __dict__
class F1(object):
    '''
    
这里是F1类
    '''
    
def __init__(self,name,age):
        self.name = name
        self.age = age
    def func(self):
        pass

obj = F1('aaa',23)
print(obj.__dict__)  # {'name': 'aaa', 'age': 23},获取的是一个字典,这样就能获取到对象中的变量值

# __iter__
# 列表也是一个类,可以for循环,但们自己写的类就无法循环,也叫不可迭代,添加如下方法可变迭代,使用for循环
'''
class F1(object):
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def func(self):
        pass

obj = F1('aaa',23)
for item in obj:  # 报错
    print(item) 
'''

# 让类变可迭代方法如下
# 1.在类中定义__iter__方法
# 2.在iter中返回一个迭代器,或者一个生成器,生成器也是特殊的迭代器

# 第一种方法,返回迭代器iter()
'''
class F1(object):
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def func(self):
        pass
    def __iter__(self):
        return iter([11,22,33])

obj = F1('aaa',23)
for item in obj:
    print(item)
# 11
# 22
# 33
'''
# 第二种方法,返回生成器
'''
class F1(object):
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def func(self):
        pass
    def __iter__(self):
        yield 11
        yield 22
        yield 33

obj = F1('aaa',23)
for item in obj:
    print(item)

# 11
# 22
# 33
'''

 

类变量的练习题,列表

# 第三题:
"""
class StarkConfig(object):
    list_display = []

    def get_list_display(self):
        self.list_display.insert(0,33)
        return self.list_display

class RoleConfig(StarkConfig):
    list_display = [11,22]


s1 = StarkConfig()
s2 = RoleConfig()

result1 = s1.get_list_display()
print(result1) # 33

result2 = s2.get_list_display()
print(result2) # 33,11,22
"""

# 第四题:
"""
class StarkConfig(object):
    list_display = []

    def get_list_display(self):
        self.list_display.insert(0,33)
        return self.list_display

class RoleConfig(StarkConfig):
    list_display = [11,22]


s1 = RoleConfig()
s2 = RoleConfig()

result1 = s1.get_list_display()
print(result1) # 33,11,22

result2 = s2.get_list_display()
print(result2)  # 33,33,11,22
"""

 

issubclass, type, isinstance  

# issubclass
class Foo(object):
    pass
class Bar(Foo):
    pass

print(issubclass(Foo,Bar)) # 第一个参数是子类,第二个是父类
# False
print(issubclass(Bar,Foo))
# True

# type   判断对象是不是由某一个指定类?
obj = Foo()
print(type(obj))  # <class '__main__.Foo'>
if type(obj) == Foo:
    print('obj是Foo的对象')   # obj是Foo的对象

# 当将一堆对象传给一个函数时,如何判断一个对象是那个类的
def func(*args):
    foo_count = 0
    bar_count = 0
    for item in args:
        if type(item) == Foo:
            foo_count += 1
        elif type(item) == Bar:
            bar_count += 1
    return foo_count,bar_count

s1,s2 = func(Foo(),Bar(),Foo())
print(s1,s2)   # 2 1

# isinstance   检查第一个参数(对象)是否是第二个参数(类及父类)的实例
class Foo(object):
    pass
class Bar(Foo):
    pass
class Base(Bar):
    pass

obj = Base()
print(isinstance(obj,Foo))  # True   # 检查第一个参数(对象)是否是第二个参数(类及父类)的实例
print(isinstance(obj,Bar))  # True
print(isinstance(obj,Base)) # True

obj1 = Bar()
print(isinstance(obj1,Foo))  # True
print(isinstance(obj1,Bar))  # True
print(isinstance(obj1,Base)) # False

"""
给你一个参数,判断对象是不是由某一个指定类? type                  --> type(obj) == Foo
给你一个参数,判断对象是不是由某一个指定类或其父类? isinstance    --> instance(obj,Foo)
"""

 

方法和函数(不重要)

              称谓:

                     类,方法

                     外,函数

              到底方法函数?

                     对象.xxx  --> xxx就是方法

                     类.xxx    --> xxx就是函数

                     xxx       --> xxx就是函数

              打印查看:

                     function

                     method

                    

              代码检查:

                     from types import MethodType,FunctionType

                     def check(arg):

                            """

                            检查arg是方法还是函数?

                            :param arg:

                            :return:

                            """

                            if isinstance(arg,MethodType):

                                   print('arg是一个方法')

                            elif isinstance(arg,FunctionType):

                                   print('arg是一个函数')

                            else:

                                   print('不知道是什么')

 

反射

总结:

v = getattr(obj,"func")  # 根据字符串为参数(第二个参数),去对象(第一个参数)中寻找与之同名的成员。

好记:

                     getattr # 根据字符串的形式,去对象中找成员。

                     hasattr # 根据字符串的形式,去判断对象中是否有成员。

                     setattr # 根据字符串的形式,动态的设置一个成员(内存)

                     delattr # 根据字符串的形式,动态的删除一个成员(内存)

 

具体实例见day25

 

问题:你见过那些加()

                     类(),函数(),方法(),对象()是执行__call__方法

可以通过callable(方法/类,函数,对象)判断

 

 

Day 26

约束   ***

class BaseMessage(object):

       def send(self):

              """

              必须继承BaseMessage,然后其中必须编写send方法。用于完成具体业务逻辑。

       """

       raise NotImplementedError(".send() 必须被重写.")

       # raise Exception(".send() 必须被重写.")

                                  

       BaseMessage类用于约束,约束其派生类:保证派生类中必须编写send方法,不然执行可能就会报错。

 

总结:

1. 什么是接口以及作用?

接口时一种数据类型,主要用于约束派生类中必须实现指定的方法。

Python中不存在,Java和C# 中是存在的。

2. Python中使用过什么来约束呢?

       - 抽象类+抽象方法,编写上麻烦。

       - 人为主动抛出异常

3. 约束时,抛出的异常是否可以用其他的?

       不专业:raise Exception(".send() 必须被重写.")

       专业:raise NotImplementedError(".send() 必须被重写."    

4. 以后看代码,揣摩心思 

5. 写代码:

class BaseMessage(object):

def send(self,x1):

              """

              必须继承BaseMessage,然后其中必须编写send方法。用于完成具体业务逻辑。

              """

              raise NotImplementedError(".send() 必须被重写.")

 

class Email(BaseMessage):

       def send(self,x1):

              """

              必须继承BaseMessage,然后其中必须编写send方法。用于完成具体业务逻辑。

              """

              print('发送邮件')

 

obj = Email()

obj.send(1)

                           

6. 应用场景:

       多个类,内部都必须有某些方法时,需要使用基类+异常进行约束。

 

自定义异常类         ***

# 通过自定义异常类,捕获到异常,返回自己想要的信息
# 知识点:如何自定义异常类
class MyException(Exception):
    def __init__(self,code,msg):
        self.code = code
        self.msg = msg

try:
    # 代码块
    raise MyException(1000,'操作异常') 

except KeyError as obj:
    print(obj,111)
except MyException as obj:  # 捕获异常
    print(obj,222)
except Exception as obj: # 当发生了自己没有预料到的异常
    print(obj,333)

 

加密 hashlib           *****

# 示例二
# 当用通用的md5加密时,可能能在网上破解,因此可以在实例化的时候加盐,达到算出不一样的md5加密

obj1 = hashlib.md5(b'd4df')
obj1.update('admin'.encode('utf-8'))
# 获取密文
print(obj1.hexdigest()) # ef8470e742484678a6307585a209e5fa

# 示例三
# 当在实际使用中,用户输入用户名,保存在数据库中,此时的数据必须加密,当在
# 验证时,可以将用户输入的密码加密,和数据库中的密文进行对比,
def md5(pwd):
    obj3 = hashlib.md5(b'd4df')
    obj3.update('admin'.encode('utf-8'))
    return obj3.hexdigest()

user = input('请输入用户名:')
pwd = input('请输入密码:')
if user == 'admin' and md5(pwd) == 'ef8470e742484678a6307585a209e5fa':
    print('登录成功')

 

日志logging        ****  

import logging
logger = logging.basicConfig(filename='log.txt',
                             format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
                             datefmt='%Y-%m-%d %H:%M:%S',
                             level=30)
logging.debug('level-10')
logging.info('level-20')
logging.warning('level-30')
logging.error('level-40')
logging.critical('level-50')

# 以上是日志对应的级别,config里面为对应的日志内容,可以直接copy
import traceback
def func():
    try:
        a = a +1
    except Exception as e:
        # 获取当前错误信息的堆栈信息
        logging.error(traceback.format_exc())
func()

 

多日志文件

import logging
# 创建一个操作日志的对象logger(依赖FileHandler)
file_handler = logging.FileHandler('1.log','a',encoding='utf-8')
file_handler.setFormatter(logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s"))

logger1 = logging.Logger('s1',level=logging.ERROR)
logger1.addHandler(file_handler)
logger1.error('将错误信息写入1.log文件中')


# 再创建一个操作日志的对象logger(依赖FileHandler)
file_handler1 = logging.FileHandler('2.log','a',encoding='utf-8')
file_handler1.setFormatter(logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s"))

logger2 = logging.Logger('s2',level=logging.ERROR)
logger2.addHandler(file_handler1)
logger2.error('将错误信息写入2.log文件中')

 

 

argparse模块

argsparse是python的命令行解析的标准模块

# ##分析传入参数
parser = ArgumentParser(description='manual to this script')
parser.add_argument('--case', type=str, default='')
parser.add_argument('--service', type=str, default='')
args = parser.parse_args()

 

Cmd下

python main.py --case projects.service.verifyservice

打印args结果为

Namespace(case='projects.service.verifyservice', service='')

 

可选参数

为了在命令行中避免上述位置参数的bug(容易忘了顺序),可以使用可选参数,这个有点像关键词传参,但是需要在关键词前面加(以上实例就是可选参数,如果去掉—就是位置参数需要一一对应)

默认值

add_argument中有一个default参数。有的时候需要对某个参数设置默认值,即如果命令行中没有传入该参数的值,程序使用默认值。如果命令行传入该参数,则程序使用传入的值

必需参数

add_argument有一个required参数可以设置该参数是否必需。required=True

parser.add_argument('--name', type=str, required=True, default='', help='名')

 

configparser模块简介

以下是 configparser 模块的基本方法:

  • 读取配置文件
  • defaults() 返回包含实例范围默认值的字典
  • read(filename) 直接读取ini文件内容
  • sections() 获取所有的 section,以列表的形式返回
  • options(section) 获取指定 section 的所有的 option
  • items(section) 获取指定 section 所有的键值对
  • get(section, option) 获取指定 section 中 option 的值
  • getint(section, option) 获取指定 section 中 option 的值,以 int 类型返回
  • getfloat(section, option) 获取指定 section 中 option 的值,以 float 类型返回
  • getboolean(section, option) 获取指定section 中 option 的值,以 boolean类型返回
  • 写入配置文件
  • add_section(section) 添加指定的新的 section
  • has_section(section) 判断是否存在指定的 section
  • set(section, option, value) 设置指定 section 中 option 的值
  • remove_section(section) 删除指定 section
  • remove_option(section, option) 删除指定 section 中的 option
  • write(fileobject) 将内容写入配置文件

 

https://blog.csdn.net/atlansi/article/details/83243478

 

 

 

importlib模块

Python中动态导入对象importlib.import_module()的使用

一个函数运行需要根据不同项目的配置,动态导入对应的配置文件运行。

from importlib import import_module

or

import importlib

im = importlib.import_module()

 

posted @ 2020-07-25 09:08  Aline2  阅读(100)  评论(0编辑  收藏  举报