Skip to content

Python学习笔记

函数式编程

  1. lambda表达式

    f = lambda x: x * x
    y = f(5) # 25
    

  2. map函数

    m1 = map(lambda x: x * x, [1, 2, 3, 4, 5])
    y1 = list(m1) # [1, 4, 9, 16, 25]
    m2 = map(str, [1, 2, 3, 4, 5])
    y2 = list(m2) # ['1', '2', '3', '4', '5']
    

  3. reduce函数

    from functools import reduce
    r = reduce(lambda x, y: x + y, [1, 2, 3, 4, 5]) # 15
    

  4. filter函数

    f = filter(lambda x: x % 2 == 0, [1, 2, 3, 4, 5])
    y = list(f) # [2, 4]
    

  5. sorted函数

    s = sorted([(1, 2), (3, 1), (2, 3)], key=lambda x: x[1]) 
    # [(3, 1), (1, 2), (2, 3)]
    

  6. partial函数

    from functools import partial
    def add(x, y):
        return x + y
    add2 = partial(add, 2)
    y = add2(3) # 5
    

  7. zip函数

    z = zip([1, 2, 3], [4, 5, 6])
    y = list(z) # [(1, 4), (2, 5), (3, 6)]
    

  8. 函数闭包

    函数闭包即嵌套函数可以访问外层的变量,即使外层函数已经执行完毕。

    def outer(x):
        def inner(y):
            return x + y
        return inner
    f = outer(2)
    y = f(3) # 5
    

面向对象编程

  1. 下划线命名规则

    • _var:私有属性,不应该被外部访问
    • __var:私有属性,会被Python解释器重命名,避免子类覆盖父类的属性
    • __var__:魔术方法或特殊方法,如__init____str__
      class A:
          def __init__(self):
              self._var = 1
              self.__var = 2
              self.__var__ = 3
          def __str__(self):
              return 'A'
      
      a = A()
      print(a._var) # 1, not recommended
      print(a.__var) # AttributeError
      print(a._A__var) # 2
      print(a.__var__) # 3
      print(a) # A
      
  2. 类的继承

    class A:
        def __init__(self):
            self.var = 1
        def func(self):
            return 'A'
    class B(A):
        def __init__(self):
            super().__init__()
            self.var = 2
        def func(self):
            return 'B'
    
    b = B()
    print(b.var) # 2
    print(b.func()) # B
    

  3. 多重继承

    通过MRO(Method Resolution Order)来确定方法的调用顺序。

    class A:
        def func(self):
            return 'A'
    class B:
        def func(self):
            return 'B'
    class C(A, B):
        pass
    
    c = C()
    print(c.func()) # A
    print(C.__mro__) # (<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
    

  4. 类的属性

    class A:
        var = 1
        def __init__(self):
            self.var = 2
    a = A()
    print(a.var) # 2
    print(A.var) # 1
    

  5. 类的方法与静态方法

    class A:
        @classmethod
        def func(cls):
            return cls
        @staticmethod
        def func2():
            return 'static'
    a = A()
    print(a.func()) # <class '__main__.A'>
    print(A.func()) # <class '__main__.A'>
    print(A.func2()) # static
    

  6. 类的特殊方法

    class A:
        # 构造函数
        def __init__(self, var):
            self.var = var
        # 析构函数
        def __del__(self):
            print('delete')
        # 字符串表示
        def __str__(self):
            return str(self.var)
        def __repr__(self):
            return 'A(' + str(self.var) + ')'
        # 运算
        def __add__(self, other):
            return A(self.var + other.var)
        def __eq__(self, other):
            return self.var == other.var
        def __call__(self, param):
            print(param)
            return self.var
        # 字典
        def __getitem__(self, key):
            return self.var[key]
        def __setitem__(self, key, value):
            self.var[key] = value
        def __delitem__(self, key):
            del self.var[key]
    a = A(1)
    print(a) # 1
    print(repr(a)) # A(1)
    
    c = a + a
    print(c) # 2
    del c # delete
    print(a == A(1)) # True
    a('call') # call
    
    b = A({'a': 1})
    print(b['a']) # 1
    b['b'] = 2
    print(b['b']) # 2
    del b['a']
    print(b) # {'b': 2}
    

元编程

  1. 迭代器

    元素不会一次性全部加载到内存中,而是在需要的时候才加载。

    class A:
        def __init__(self):
            self.data = [1, 2, 3]
        def __iter__(self):
            self.index = 0
            return self
        def __next__(self):
            if self.index < len(self.data):
                self.index += 1
                return self.data[self.index - 1]
            else:
                raise StopIteration
    a = A()
    # 1 2 3
    for i in a:
        print(i)
    
    i = iter(a)
    print(list(i)) # [1, 2, 3]
    
    i = iter(a)
    print(next(i)) # 1
    print(next(i)) # 2
    print(next(i)) # 3
    print(next(i)) # StopIteration
    

  2. 生成器

    生成器是一种特殊的迭代器,可以通过yield关键字来实现。在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。

    def fibonacci(n): # 生成器函数 - 斐波那契
        a, b, counter = 0, 1, 0
        while True:
            if (counter > n): 
                return
            yield a
            a, b = b, a + b
            counter += 1
    f = fibonacci(10) # f 是一个迭代器,由生成器返回生成
    
    while True:
        try:
            print (next(f), end=" ")
        except StopIteration:
            break
    

  3. 装饰器

    装饰器是一种特殊的函数,可以在不改变原函数的情况下,对函数进行扩展。

    import time
    def get_time(func):
        startTime = time.time()
        func()
        endTime = time.time()
        processTime = (endTime - startTime) * 1000
        print ("The function timing is %f ms" %processTime)
    
    @get_time
    def myfunc():
        print("start")
        time.sleep(0.8)
        print("end")
    
    Python中,常见的类装饰器包括:@staticmathod、@classmethod和@property - @staticmethod:类的静态方法,跟成员方法的区别是没有self参数,并且可以在类不进行实例化的情况下调用。 - @classmethod:跟成员方法的区别是接收的第一个参数不是self,而是cls(当前类的具体类型) - @property:表示可以直接通过类实例直接访问的信息。
    class MyClass:
        def __init__(self):
            self._my_property = None  # 私有属性
    
        @property
        def my_property(self):
            """Getter 方法"""
            print("Getting my_property")
            return self._my_property
    
        @my_property.setter
        def my_property(self, value):
            """Setter 方法"""
            print("Setting my_property")
            self._my_property = value
    
        @my_property.deleter
        def my_property(self):
            """Deleter 方法"""
            print("Deleting my_property")
            del self._my_property
    
    obj = MyClass()
    obj.my_property = 42
    print(obj.my_property) # 输出: Getting my_property
                           #       42
    del obj.my_property    # 输出: Deleting my_property
    

  4. 动态修改对象的属性

    class MyClass(object):
        def __init__(self, name):
            self.name = name
    
    property_name = "age" if True else "gender"
    obj = MyClass("John")
    setattr(obj, property_name, 25)
    print(getattr(obj, property_name))  # 输出: 25
    print(hasattr(obj, property_name))  # 输出: True
    delattr(obj, property_name)
    

  5. 动态修改类的属性

    # 创建类
    class MyClass(object):
        def __init__(self, name):
            self.name = name
    
    my_function = lambda x, y: x + y
    method_name = "my_method"
    setattr(MyClass, method_name, my_function)
    print(getattr(MyClass, method_name)(2, 3))  # 输出: 5
    print(hasattr(MyClass, method_name))  # 输出: True
    delattr(MyClass, method_name)
    

  6. 创建动态类与动态属性

    class_dict = {
        "name": "MyClass",
        "bases": (object,),
        "dict": {
            "__init__": lambda self, x: setattr(self, "x", x),
            "__str__": lambda self: str(self.x),
            "hello": lambda self: print("Hello!"),
        },
    }
    MyClass = type(class_dict["name"], class_dict["bases"], class_dict["dict"])
    
    property_name = "p"
    def property_getter(self): 
        return self.__dict__[property_name]
    def property_setter(self, value): 
        print("Setting", property_name, "to", value)
        self.__dict__[property_name] = value
    def property_deleter(self): 
        print("Deleting", property_name)
        del self.__dict__[property_name]
    
    setattr(MyClass, property_name, 
            property(property_getter, property_setter, property_deleter))
    
    a = MyClass(42)
    a.hello() # Hello!
    a.p = 100 # Setting p to 100
    del a.p   # Deleting p
    
    动态属性创建之后的行为与前文的@property装饰器创建的属性行为一致。

  7. 元类

    元类是构建类的类,可以通过元类来控制类的创建行为。 普通的类继承自object,而元类继承自type, type是Python中所有对象的祖先类型,而object是所有类的父类。

    int.__class__ # <class 'type'>
    int.__bases__ # (<class 'object'>,)
    type.__class__ # <class 'type'>
    type.__bases__ # (<class 'object'>,)
    object.__class__ # <class 'type'>
    object.__bases__ # ()
    
    type,object是互相依赖的两个源对象。
    import types
    
    def trace(func):
        def callfunc(self, *args, **kwargs):
            print('Calling %s: %s ,%s'%(func.__name__, args, kwargs))
            result = func(self, *args, **kwargs)
            print('%s returned %s'%(func.__name__, result))
            return result
        return callfunc
    
    class LogMeta(type):
        def __new__(cls, name, bases, attr_dict):
            for k, v in attr_dict.items():
                if isinstance(v, types.FunctionType):
                    # 如果v是函数类型, 使用trace处理,添加日志
                    attr_dict[k] = trace(v)
            # 添加hello方法
            attr_dict['hello'] = lambda self: print('Hello')
            return type.__new__(cls, name, bases, attr_dict)
    
    class Foo(object, metaclass=LogMeta):
        num = 0
        def spam(self):
            Foo.num += 1
            return Foo.num
    
    f = Foo()
    f.hello() # Hello
    f.spam() # Calling spam: (f,),{}
             # spam returned 1
    f.spam() # Calling spam: (f,),{}
             # spam returned 2
    print(Foo.num) # 2
    

  8. 变量管理

    globals()关键字用于在函数或其他局部作用域中使用全局变量。

    x = 10
    def foo():
        x = 20
        globals()['x'] = 30
        print(x) # 20
        print(globals()['x']) # 30
    foo()
    
    locals()函数会以字典类型返回当前位置的全部局部变量。
    def calculate(a, b):
        result = a + b
        # 显示当前作用域的所有局部变量
        print(locals())
        return result
    
    calculate(3, 4) # {'a': 3, 'b': 4, 'result': 7}
    
    vars()函数会以字典类型返回对象的__dict__属性。
    class DynamicClass:
        pass
    
    obj_dynamic =DynamicClass()
    
    # 动态添加属性
    vars(obj_dynamic)['new_attr']="Newly added attribute"
    print(vars(obj_dynamic))
    
    # 修改已有属性
    vars(obj_dynamic)['new_attr']="Modified attribute"
    print(vars(obj_dynamic))