Python高级编程知识总结(1)

Python高级编程知识总结(1)

Posted by 王正午 on June 15, 2020

python中一切皆对象

在Python中函数和类也是对象,属于Python的一等公民
1. 可以赋值给一个变量
    # 函数可以被赋值给变量
    def hello(name='world'):
        print('hello ' + name)
    
    my_func = hello
    my_func('python')
    
    # 类可以被赋值给变量
    class Person:
        def __init__(self):
            print('__init__')
    
    my_class = Person
    my_class()
2.可以添加到集合对象中
    # 定义集合对象
    obj_list = []
    # 添加方法与类到几个中
    obj_list.append(hello)
    obj_list.append(Person)
    
    for item in obj_list:
        print(item())
        
    输出结果  hello word
             None
             __init__
             <__main__.Person object at 0x106cf7940>
3.可以作为参数传递给函数
    # 输出类型
    def print_type(item):
        print(type(item))
    
    for item in obj_list:
        print_type(item)
        
    输出结果 <class 'function'>
            <class 'type'>
4.可以当做函数返回值
def decorator_func():
    print('调用decorator_func函数')
    return hello

my_func = decorator_func()
my_func('python')
    
    输出结果 调用decorator_func函数
            hello python

type object class 之间的关系

avatar

代码实例

a = 1
type(1)
#Out[3]: int
#type(int)
#Out[4]: type
说明:
由上面的代码可以知道,type生成了int,int生成1
因此是由type生成了类对象,再有类对象生成了实例
type->class->obj
    
class Student:
    pass
class MyStudent(Student):
    pass
    #MyStudent.__bases__
   # Out[10]: (__main__.Student,)
   # Student.__bases__
   # Out[11]: (object,)
        
说明:由上面的代码我们可以看出bject是最顶层的基类

type 是一个特殊且重要的对象,type既是一个类,也是一个对象,type的基类是object,object又是由type生成的,
所以最上方的图就刚好描述了整个流程

Python中的内置类型

   • None(全局只有一个)

  • 数值

  • 迭代类型

  • 序列类型

  • 映射(dict)

  • 集合

  • 上下文管理类型(with)

   • 其他

魔法函数

1、__init__():
所有类的超类object,有一个默认包含pass的__init__()实现,这个函数会在对象初始化的时候调用,我们可以选择实现,也可以选择不实现,
一般建议是实现的,不实现对象属性就不会被初始化,虽然我们仍然可以对其进行赋值,但是它已经成了隐式的了,编程时显示远比隐式的更好
2、__str__():
直接打印对象的实现方法,__str__是被print函数调用的,一般都是return一个什么东西,这个东西应该是以字符串的形式表现的,
如果不是要用str()函数转换,我们可以直接print的对象都是实现了__str__这个方法的,比如dict。
3、__new__():
在object类中存在一个静态的__new__(cls, *args, **kwargs)方法,该方法需要传递一个参数cls,cls表示需要实例化的类,此参数在实例化时由Python解释器自动提供,__new__方法必须有返回值,
且返回的是被实例化的实例,只有在该实例返回后才会调用__init__来进行初始化,初始化所用的实例就是__new__返回的结果,也就可以认为是self,
4、__unicode__():
__unicode__()方法是在一个对象上调用unicode()时被调用的。因为Django的数据库后端会返回Unicode字符串给model属性,所以我们通常会给自己的model写一个__unicode__()方法。
如果定义了__unicode__()方法但是没有定义__str__()方法,Django会自动提供一个__str__()方法调用 __unicode__()方法,然后把结果转换为UTF-8编码的字符串对象,所以在一般情况下,
只定义__unicode__()方法,让 Django来处理字符串对象的转换,
5、__len__():
len调用后会调用对象的__len__函数,一般用来计算可迭代对象的长度

以上是整理的一小部分常用魔法函数,魔法函数不受类的约束,并不是一定要实现的方法。

详细魔法函数介绍

鸭子类型和多态

鸭子类型:
当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来像鸭子、叫起来也像鸭子、那么这只鸟就可以被称为鸭子

class Cat(object):

    @staticmethod
    def say():
        print('i am cat')


class Dog(object):

    @staticmethod
    def say():
        print('i am dog')


class Duck(object):

    @staticmethod
    def say():
        print('i am duck')


animal_list = [Cat, Dog, Duck]
for animal in animal_list:
    animal().say()

输出结果:
    i am cat
    i am dog
    i am duck
   
上述class都实现了一个名为say的方法,那么我们可以把这些的类,都归于一种类型,在python中实现多态,只需要去实现相同名称的方法就可以了,
(多态都是子类覆盖超类的方法,不同的实例访问的方法不同,都是先访问自己的,自己没有再去找超类的方法)

抽象基类

抽象基类有两个特点:
1.规定继承类必须具有抽象基类指定的方法
2.抽象基类无法实例化

抽象基类无法实例化基于上述两个特点,
抽象基类主要用于接口设计实现抽象基类可以使用内置的abc模块

代码


import abc
class Human(metaclass=abc.ABCMeta):
    @abc.abstractmethod   # 规定子类必须有名为introduce的实例方法
    def introduce(self):
        pass
    
    @abc.abstractproperty  # 规定子类必须有名为country的装饰器方法
    def country(self):
        pass
    
    @abc.abstractclassmethod  # 规定子类必须有名为gender的类方法
    def gender(cls):
        pass
    @abc.abstractstaticmethod  # 规定子类必须有名为hello的静态方法
    def hello():
        pass
class Person(Human):
    __country = "China"
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def introduce(self):
        return "I'm {}, {}.".format(self.name, self.age)
    
    @property
    def country(self):
        return Person.__country
    
    @classmethod
    def gender(cls):
        return "female"
    
    @staticmethod
    def hello():
        print("What the hell?")

person = Person("Li", 24)
print(person.introduce())
print(person.country)
print(Person.gender())
person.hello()

# I'm Li, 24.
# China
# female
# What the hell?

instance 和 type的区别

instance和type都是用来验证某个对象的类型的,它们的区别如下:
type()不会认为子类是一种父类类型,而instance会认为子类也是一种父类类型.

isinstance() #函数来判断一个对象是否是一个已知的类型,类似 type()。
isinstance() #与 type() 区别:
type() #不会认为子类是一种父类类型,不考虑继承关系。
isinstance() #会认为子类是一种父类类型,考虑继承关系。
#如果要判断两个类型是否相同推荐使用 isinstance()。
# 例一
a = 2
print(isinstance(a,int))   # True
print(isinstance(a,str))   # False

# type() 与 isinstance() 区别
class A:
    pass

class B(A):
    pass

print("isinstance",isinstance(A(),A))   # isinstance True
print("type",type(A())  == A)    # type True

print('isinstance',isinstance(B(),A) )   # isinstance True
print('type',type(B()) == A)     #  type False

类变量和实例变量

类变量:可在类的所有实例之间共享的值(也就是说,它们不是单独分配给每个实例的)。
实例变量:实例化之后,每个实例单独拥有的变量。

class student():
    age = 0
    name = 'stu'
    # age,name是类变量
    def __init__(self,age,name):
        self.age = age
        self.name = name
    # 访问实例变量(用self.age  self.name)
    
student1 = student(18,'hello')
print(student1.name) 
# 打印实例变量,输出hello
print(student.name)  
# 打印类变量,输出stu

Python类变量被赋值
(1)类的设计里,
class里def外,通过变量名能被赋值
def里通过类对象即类名字的点运算变量名可被赋值
(2)程序里
通过类对象(类名字)的点运算类名字也可被赋值
Python实例对象变量被赋值
(1)类的设计时
def里通过self点运算变量名能被赋值,不一定非在init里,其他已被调用的方法函数里也行
(2)程序里
通过实例对象的点运算变量名可被赋值
类变量和实例变量的区别在于:类变量是所有对象共有,其中一个对象将它值改变,其他对象得到的就是改变后的结果;而实例变量则属对象私有,某一个对象将其值改变,不影响其他对象