美文网首页
Python学习笔记2020-02-25

Python学习笔记2020-02-25

作者: 翔的鱼 | 来源:发表于2020-02-25 22:01 被阅读0次

    02-25
    今天生日,学习笔记也从今天开始记录
    直到今天为止,一共学习了12天,首先,先来复习一下Day01的课程

    Day 01

    第一天主要的作用是了解Python,安装Python和Pycharm编译器
    Python的作用在这就不多做解释,网上很多方面的应用

    • 安装Python
      百度直接搜索Python,选择Python3下载 或者 点击Python进入官网下载
      双击下载包即可安装
    • 安装Pycharm
      同理,去百度搜索,或者去Pycharm官网下载
      速度可能有点慢,别着急
      双击下载包即可安装

    接下来是今天的学习笔记 Day12
    仅个人理解,有问题请指出!

    Day12

    1.self的使用

    self在定义__init__的时候会自动声明,用来传递关键类传入的参数,例如

    class Person(object):
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def eat(self):
            print(self.name + '正在吃东西')
    
    
    p1 = Person('张三', 18)
    p2 = Person('李四', 20)
    
    p1.eat()
    

    p1调用eat()方法的时候,self获取的是p1当中的name
    如果p2调用eat()方法的话,self获取的是p2当中的name

    2.运算符相关的魔法方法

    • 魔法方法__eq__
      当使用==比较两个值/数时,会自动调用__eq__方法,可以在class类里重新编写
      例如
    class Person:
        def __init__(self, name, age):
            self.name = name
            self.age = age
    print(p1 == p2)  # False
    

    修改前print(p1 == p2)的结果为False

    class Person:
        def __init__(self, name, age):
            self.name = name
            self.age = age
        def __eq__(self, other):
            return self.name == other.name and self.age == other.age
    print(p1 == p2)  # True == 运算符本质是调用对象的 __eq__ 方法的返回结果 重写以后可以变为True
    

    修改后print(p1 == p2)的结果为True

    • 魔法方法__add__,__sub__,__mul__,__truediv__对应加减乘除
      当使用+ - * /的时候自动调用
        def __add__(self, other):
            return self.age + other.age
    

    return self.age + other.age+可以替换成- * /来对应相应的魔法方法

    • 魔法方法__int__,__float__
      在使用int()或者float()时会自动使用,在这就不做演示

    3.内置属性

    • __slots__ = ('name','age')表示能出现的属性有name和age
    class Person(object):
        '''
        这是一个人类
        '''
    
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        __slots__ = ('name', 'age')  # 能出现的属性
    
    • __dict__把对象属性和值转换成为一个字典
    • __dir__等价于dir()用来查看所有属性和方法
    • __doc__查看类中的说明,使用方法可以有一下两种
    print(p.__doc__)  # 对象名.__doc__
    print(Person.__doc__)  # 类名.__doc__
    

    4.把对象当做字典使用

    class Person(object):
        '''
        这是一个人类
        '''
    
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def eat(self):
            print(self.name + '正直吃饭')
    
        def __setitem__(self, key, value):
            self.name = value
    
        def __getitem__(self, item):
            return self.__dict__[item]
    
    
    p = Person('张三', 18)
    print(p.__dict__)  # {'name': '张三', 'age': 18} 把对象属性和值转换成为一个字典
    
    # 不能直接把一个对象当做字典使用
    p['name'] = 'jack'  # 在未编写__setitem__方法时会报错
    print(p.name)
    print(p['name'])  # 会调用__getitem__方法(同样要编写以后才能调用)
    

    5.对象属性和类属性

    class Person(object):
        type = '人类'
        '''
        这是一个人类
        '''
    
        def __init__(self, name, age):
            self.name = name
            self.age = age
    

    此时先定义了一个类属性

    # 对象 P1 和 p2 都是通过 Person 类创建出来的实例对象
    # name 和 age 是对象属性,在__init__方法里以参数的形式定义的
    # 是每一个实例对象都会单独保存一份的属性
    # 没一个实例对象之间的属性没有关联,互不影响
    p1 = Person('张三', 18)
    p2 = Person('李四', 19)
    # 类属性可以通过类对象和实例对象获取
    print(Person.type)  # 人类 可以通过类对象寻找类属性
    # 也可以通过实例对象寻找类属性
    print(p1.type)  # 人类
    print(p2.type)  # 人类
    

    此时更改p1.type = 'human'这时是新增了一个对象属性,不是覆盖

    p1.type = 'human'
    print(Person.type)  # 人类
    print(p1.type)  # human 新增了一个对象属性
    print(p2.type) # 人类
    

    当我们修改Person.type = 'monkey'

    # 类属性只能通过类对象来修改,实例对象无法修改类属性
    
    Person.type = 'monkey'
    print(Person.type)  # monkey
    print(p1.type)  # human
    print(p2.type)  # monkey
    

    6.私有属性

    在定义类的时候,使用双下划线来定义私有属性/方法

    class Person(object):
        def __init__(self, name, age):
            self.name = name
            self.age = age
            self.__money = 1000  # 以两个下划线定义的变量是私有变量
        def __demo(self):
            print('我是demo函数,name={}'.format(self.name))
    

    如何获取私有属性呢?
    1.使用对象._类名__私有变量名获取

    print(p._Person__money)  # 通过这种方式也能获取到私有属性
    

    2.定义get和set方法进行获取

    class Person(object):
        def __init__(self, name, age):
            self.name = name
            self.age = age
            self.__money = 1000
        def get_money(self):
            # 记录
            print('{}查询余额.'.format(datetime.datetime.now()))
            return self.__money
        def set_money(self, qian):
            if type(qian) != int:
                print('设置的余额不合法')
                return
            print('修改余额了')
            self.__money = qian
        def __demo(self):
            print('我是demo函数,name={}'.format(self.name))
        def test(self):
            self.__demo()
    
    p = Person('张三', 18)
    p.test()  # 我是demo函数,name=张三
    print(p.get_money())
    # 2020-02-25 21:47:05.297043查询余额.
    # 1000
    p.set_money(100)
    # 修改余额了
    print(p.get_money())
    #2020-02-25 21:47:05.297043查询余额.
    #100
    

    7.类方法和静态方法

    class Person(object):
        type = '人类'
    
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def eat(self, food):  # 对象方法有一个参数self,指的是实例对象
            print(self.name + '正在吃' + food)
        # 如果一个方法里没有用到任何的实例对象的任何属性,可以将这个方法定义成static(静态方法)
        @staticmethod
        def demo():  # 默认分方法都是对象方法
            print('hello')
    
        @classmethod
        def test(cls):  # 如果这个函数只用到了类属性,我们可以把他定义成为一个类方法
            # 类方法会有一个参数cls,也不需要手动传参,会自动传参
            # cls 指的是类对象 cls == Person # True
            print(cls.type)
            print('yes')
    class Calculator():
        @staticmethod  
        # 如果一个方法里没有用到任何的实例对象的任何属性,可以将这个方法定义成static(静态方法)
        def add(a, b):
            return a + b
    
        @staticmethod
        def minus(a, b):
            return a - b
    
        @staticmethod
        def mul(a, b):
            return a * b
    
    
    c = Calculator()
    print(c.add(1, 2))
    print(Calculator.add(1, 2))
    print(Calculator.minus(4, 3))
    print(Calculator.mul(3, 4))
    
    p1 = Person('张三', 18)
    # 实例对象在调用方法时,不需要给形参self传参,会自动把实例对象传递给self
    p1.eat('饺子')
    
    p2 = Person('李四', 19)
    
    # print(p1.eat)
    # print(p2.eat)
    print(p2.eat is p1.eat)
    
    print(Person.eat)
    
    # 对象方法还可以使用 类对象来调用类名.方法名()
    # 这种方式,不会自动给self传参,需要手动的指定self
    # Person.eat('西红柿鸡蛋盖饭')  # eat() missing 1 required positional argument: 'food'
    
    # staticmethod 没有用到类和实例对象内部中函数的参数,所以可以直接调用
    Person.demo()
    p1.demo()
    
    # classmethod类方法
    p1.test()
    Person.test()
    

    总结:静态方法可以通过类名.方法名直接调用,而类方法只能通过创建一个对象以后通过对象名.方法名使用,如果使用类名.方法名使用则会报错.

    8.单列设计模式

    class Singleton(object):
        instance = None  # 类属性
        __is_first = True
        def __new__(cls, *args, **kwargs):
            if cls.instance is None:
                # 申请内存,创建一个对象,并把对象的类型设置为cls
                cls.instance = object.__new__(cls)
            return cls.instance
    
        def __init__(self, a, b):
            if self.__is_first:
                self.a = a
                self.b = b
                self.__is_first = False
    
    
    # 1.调用__new__方法申请内存
    # 如果重写 __new__ 方法 , 会调用 object 的 __new__ 方法
    # object的__new__方法会申请内存
    # 如果重写了__new__方法,需要自己手动申请内存
    s1 = Singleton('呵呵', '嘿嘿嘿')
    s2 = Singleton('哈哈', '嘻嘻嘻')
    s3 = Singleton('嘎嘎', '嘤嘤嘤')
    
    print('0x%X' % id(Singleton))
    print(s1 is s2)  # True
    
    print(s1.a, s2.a)
    print(s1.b, s2.b)
    print(s1.a, s1.b)
    # print(type(s1))
    

    __new__还不是很能理解,求教导!

    相关文章

      网友评论

          本文标题:Python学习笔记2020-02-25

          本文链接:https://www.haomeiwen.com/subject/twfqchtx.html