python怎么判断一个变量是数字 python 判断变量存在_python

python怎么判断一个变量是数字 python 判断变量存在_全局变量_02

。知识不需要死记,用的时候知道查阅就好

python怎么判断一个变量是数字 python 判断变量存在_全局变量_03


python怎么判断一个变量是数字 python 判断变量存在_python_04

python怎么判断一个变量是数字 python 判断变量存在_python_04

01 - python中变量即引用,变量存在于栈内存,对象存在于堆内存,是强类型语言,动态类型语言


1class test01:
 2    # 这是一个注释
 3    def mathod01(self):
 4        print("方法一")
 5
 6    def mathod02(self):
 7        print('换行符\ 8              可以换行写')
 9        print('该对象id:' + str(id(self)))
10        print('该对象的类型:' + str(type(self)))
11        print('该类的类型:' + str(type(test01)))
12
13
14if __name__ == '__main__':
15    obj1 = test01()
16    obj1.mathod02()
# 运行结果:
换行符              可以换行写
该对象id:2674785287136
该对象的类型:<class '__main__.test01'>
该类的类型:<class 'type'>

02python内存管理即垃圾回收机制(面试的时候会用到):概括来说就是引用计数器为主,标记清除和分代回收为辅,加上缓存机制。


1. python内部维护了一个双向链表(refchain),用来存储我们创建的每一个对象,它的每一个节点包含(上一个元素地址、下一个元素地址、类型,及用计数器(ob_refcnt)和值,当引用计数器的值为0时,则将该对象从链表删除,销毁,但是仅用引用计数器会存在循环引用的问题,可能产生循环引用的类型有(list/tuple/set/dict)

2. 为了解决循环引用的问题,python引入了标记清除的方式,即python中会维护另外一个链表,用于存储可能造成循环引用的对象,不断的遍历链表,假如发现某个对象存在循环引用,则将存在循环引用的对象的引用计数器(ob_refcnt)减一,假如计数器变为0,则删除,销毁该对象。但是这样会有一个性能和时机问题,即什么时候扫描,多久扫描一次

3. 为了解决标记清除机制的扫描问题,引入了分代回收机制。即把存储可能存在循环引用的链表分为三个:0代、1代、2代

  • 0代是当存储的个数大于700个时进行一波扫描,并把扫描后剩余的对象放入一代中;
  • 1代是当0代扫描大于10次时,进行一次扫描,并把对象放入2代中;
  • 2代是1代扫描次数大于10次时,进行一波扫描。

4. 为了优化python的对象频繁创建和销毁的性能,还采用的缓存机制

  • 引入了池的概念,即python内部维护了一个-5-256整数的一个小数池,认为这些数字经常用,所以这里面的对象永远不会销毁,
  • 也维护了一个free_list的链表,即对象从ref_chain删除后,不会立马进行回收,而是先把这个对象申请的内存放入free_list中,当创建下一个对象和它类型相同时,就直接使用该内存,优化了内存的频繁申请和释放的过程。

03 - 内置数据类型:整数(int可表示任意大小)、浮点数(float)、布尔类型(Boolean)、字符串类型(str)


int(5.3)
5
 float(4)
4.0
 round(5.5)
6
round(5.4)
5
import math
math.ceil(5.9)
6
math.floor(5.1)
5

04 - 比较运算符(比较对象的值):==、!=、>、=、<=;同一运算符:is、is not 判断两个变量是否引用同一个对象


a = 1000
b = 1000
a is b
False
a == b
True

05 - 字符串


1. 字符串编码与节码
ord('中')
20013
chr(20013)
'中'

2. 字符串的拼接
'aaa'+'bbb'
'aaabbb'
'aaa''bbb'
'aaabbb'
'a' * 3
'aaa'

3. 字符串格式化操作
a = '我是{0},今年{1}'
a.format('小明','6')
'我是小明,今年6'
a = '我是{0:-^10},今年{1:.3f}'
a.format('小明',13)
'我是----小明----,今年13.000'

4.常用方法
# 判断类的
s1 = "hello world !!"
s1.isalnum() # 判断是否时字母或者数字
s1.isalpha() # 判断是否未字母
s1.is digit() # 判断是否为数字
s1.istitle() #是否单词首字母大写
s1.islower() # 是否是小写字母
s1.isupper() # 是否是大写字母
s1.isspace() # 是否是空格
# 转换类的
s1.capitalize()
s1.title()
s1.lower()
s1.upper()
s1.swapcase()
# 查找类的
s1.find() # 找不到返回-1
s1.rfind()
s1.index() # 找不到抛异常
s1.rindex()
s1.startswith()
s1.endswith()
# 格式化类的
s1.zfill() # 接受一个参数(宽度),右对齐,缺省补0
s1.ljust() # 接受两个参数,第一个为宽度,第二个为缺省填充符号
s1.rjust() # 接受两个参数,第一个为宽度,第二个为缺省填充符号
s1.center() # 接受两个参数,第一个为宽度,第二个为缺省填充符号
s1.format() # 可变参数,为字符串中对应的占位符{},从左到右0-n
# 替换类的
s1.replace()
trans = s1.maketrans(intab,outab) # 与下面连用,创建intab于outab的映射
s1.translate(trans) # 替换映射表中的字符

# 拼接类的
s1 * n #
s1 + s1
''.join(s1)
# 分割
s1.split()
list(s1)
s1[0:2]
# 删除
s1.strip()
s1.lstrip()
s1.rstrip()
# 其他
s1.count()
min(s1)
max(s1)

06 - 列表


lt1 = [1, 1, 23]
lt2 = [1, 2, 3, 4]
# list 增删改查
lt[0]
lt[::-1]
lt[1:-1]
lt.count(value)
lt.index()
lt.append(value)
lt.extend(lt2)
lt.insert(index,value)
lt[index]=value
lt.pop(index)
lt.remove(value)
del lt[index]
lt.clear()
lt.sort()
lt.reverse()

len(lt)
max(lt)
min(lt)
sum(lt)

07 - 列表与元组使用区别


# 第一个不同点,元组不可更改
a = (x*2 for x in range(6))
type(a)
<class 'generator'>a.__next__()
0a.__next__()
2b = [x*2 for x in range(6)]type(b)
<class 'list'>

08 - 字典


1. 字典创建、访问
a = (x*2 for x in range(6))
dst1 = {'a':1,'b':2}
dst2 = dict({('a',1),('b',2),('c',3)})
dst3 = dict.fromkeys(['a','b','c'])
dst4 = dict(key1=1,key2=2)
dst2.keys()
dict_keys(['b', 'a', 'c'])
dst2.values()
dict_values([2, 1, 3])
dst2.items()
dict_items([('b', 2), ('a', 1), ('c', 3)])

2.字典的增加、修改、删除
 dst1 = {'a':2,'b':3}
 dst.update(dst1)
 dst
 {'a': 2, 'b': 3}
 dst['a'] = 4
 dst
 {'a': 4, 'b': 3}
 dst.get('a')
 4
 dst.get('c','默认')
 '默认'
 dst.setdefault('c','默认') #获取当前键对应的值,如果当前健没有,则新增该键,值是设置的默认值。
 '默认'
 {'a': 4, 'b': 3, 'c': '默认'}
 dst = {'a':32,'jfkd':32,'fj':54,'fjd':4,'fso':43}
 dst.popitem()
 ('fso', 43)
 dst.pop('fj')
 54
 del dst['a']
 dst
 {'jfkd': 32, 'fjd': 4}
 dst.clear()
 dst
 {}

09 - 字典底层实现(面试可能会用到)


字典核心是个散列表,元素是bucket类型,存储位置根据健的hash值末尾几位二进制(初始为后三位,可索引长度为8的数组)作为位置,进行一系列算法来计算相应的位置,当哈希散列表储元素数量超过一定范围(2/3)时会以2的整数倍数自动扩容,重新存储所有元素到新的散列表中。

10 - 集合(set)


1. 集合的创建、删除、修改,查看
a = set()
a.add(2)
a
{2}
a ={2,3,4}
a
{2, 3, 4}
a.remove(3)
a
{2, 4}

2.集合操作
a = {23,43,'a','c'}
b = {23,'c','d'}
a|b
{'d', 23, 43, 'c', 'a'}
a -b
{43, 'a'}
a &b
{'c', 23}
a.union(b)
{'d', 23, 43, 'c', 'a'}
a.difference(b)
{43, 'a'}
a.intersection(b)
{'c', 23}

11 - python语句中常用的特殊形式


[x for x in range(11) if x % 2 == 0] # 列表推导式
[0, 2, 4, 6, 8, 10]
{a[index]:index for index in range(3)} # 字典推导式
{'a': 0, 'b': 1, 'c': 2}
{a[index] for index in range(3)} # 集合推导式
{'b', 'c', 'a'}
ss = (a[index] for index in range(3)) # 生成器推导式
ss.__next__()
'a'

12 - 全局变量与局部变量使用场景


我是全局变量 = 1


def test01():
    print('test01' + str(我是全局变量))


def test02():
    global 我是全局变量  # 修改全局变量时,要用global声明
    我是全局变量 = 2
    print('test02' + str(我是全局变量))


def test03():
    局部变量 = 'aaa'

    def inner():
        nonlocal 局部变量  # 调用外部函数的局部变量时要先声明
        局部变量 = 'cccc'
        print("inner:" + 局部变量)
    inner()
    print("test03:" + 局部变量)


if __name__ == '__main__':
    test01()
    test02()
    test03()
test011
test022
inner:cccc
test03:cccc

13 - 函数的参数传递(*args, **kwargs)


1# 无参数的装饰器
 2def proxy1(func):
 3    def process():
 4        print("前置1处理")
 5        func()
 6        print("后置1处理")
 7    return process
 8
 9# 带参数的装饰器
10def proxy2(*args, ** kwargs):
11    def proxy1(func):
12        print(args)
13        print(kwargs)
14        def process():
15            print("前置2处理")
16            func()
17            print("后置2处理")
18        return process
19    return proxy1
20# 被装饰的方法有参数时
21def proxy3(func):
22    def process(*args, **kwargs):
23        print("前置3处理")
24        func(*args, **kwargs)
25        print("后置3处理")
26    return process
27
28
29@proxy1
30def func1():
31    print('func1')
32    pass
33
34@proxy2( 1, 2, arg1='arg1',arg2='arg2')
35def func2():
36    pass
37
38@proxy3
39def func3(*args, **kwargs):
40    print(args)
41    print(kwargs)
42
43if __name__ == '__main__':
44    print("====================")
45    func1()
46    print("====================")
47    func2()
48    print("====================")
49    func3(name='小明', age='33')
 1# 无参数的装饰器
 2def proxy1(func):
 3    def process():
 4        print("前置1处理")
 5        func()
 6        print("后置1处理")
 7    return process
 8
 9# 带参数的装饰器
10def proxy2(*args, ** kwargs):
11    def proxy1(func):
12        print(args)
13        print(kwargs)
14        def process():
15            print("前置2处理")
16            func()
17            print("后置2处理")
18        return process
19    return proxy1
20# 被装饰的方法有参数时
21def proxy3(func):
22    def process(*args, **kwargs):
23        print("前置3处理")
24        func(*args, **kwargs)
25        print("后置3处理")
26    return process
27
28
29@proxy1
30def func1():
31    print('func1')
32    pass
33
34@proxy2( 1, 2, arg1='arg1',arg2='arg2')
35def func2():
36    pass
37
38@proxy3
39def func3(*args, **kwargs):
40    print(args)
41    print(kwargs)
42
43if __name__ == '__main__':
44    print("====================")
45    func1()
46    print("====================")
47    func2()
48    print("====================")
49    func3(name='小明', age='33')


运行结果: 1(

14 - lambda表达式


1fun2 = lambda a,b,c:a+b+c

15 - 类属性、类方法、静态方法、对象方法


1class model:
 2
 3    def __init__(self):
 4        self.object_arg = 'c'
 5
 6    __class_method_01 = 'a'
 7    __class_method_02 = 'b'
 8
 9    @staticmethod
10    def static_method():
11        print('这是一个静态方法')
12
13    @classmethod
14    def class_method(cls):
15        print(cls.__class_method_01)
16        print('这是一个类方法')
17
18    def objcet_method(self):
19        print(self.object_arg)

16 - python类中property的使用


1class Test:
 2    def __init__(self):
 3        self.arg1 = 14
 4
 5    @property
 6    def age(self):
 7        return self.arg1 -1
 8
 9    @age.setter
10    def age(self, age):
11        self.arg1 += age
12
13if __name__ == '__main__':
14    a = Test()
15    print(a.age)
16    a.age = 2
17    print(a.age)

17 - 经常重写的object方法


__call__
__del__
__init__
__new__
__str__
__repr__

18 - 代理设计模式


1class Person:
 2    def __init__(self):
 3        self.name = '人'
 4
 5    def work(self):
 6        pass
 7
 8    def report_name(self):
 9        pass
10
11class Student(Person):
12    def __init__(self):
13        super(Student, self).__init__()
14        self.name = '学生'
15
16    def work(self):
17        print('我是一个学生')
18
19    def report_name(self):
20        print('我的名字是:'+self.name)
21
22class Teacher(Person):
23    def __init__(self):
24        super(Teacher, self).__init__()
25        self.name = '老师'
26
27    def work(self):
28        print('我是一个老师')
29
30    def report_name(self):
31        print('我的名字是:'+self.name)
32
33def school(person):
34    if isinstance(person, Person):
35    person.work()
36    person.report_name()
37
38
39if __name__ == '__main__':
40    teacher = Teacher()
41    student = Student()
42    school(teacher)
43    school(student)
44    print(Student.mro())

19 - 单例模式的实现


import threading
def synchronized(func):
    func._lock = threading.Lock()
        def lock_func(*args, **kwargs):
            with func._lock:
                return func(*args, **kwargs)
        return lock_func

class SingleTon:
    _instance = None

    @synchronized
    def __new__(cls, *args, **kwargs):
        if cls._instance == None:
            cls._instance = super().__new__(cls)
        return cls._instance

# 运行结果
pydev debugger: process 6052 is connecting

Connected to pydev debugger (build 182.4129.34)
<__main__.singleton>0x00000238895CC9E8><__main__.singleton>0x00000238895CC9E8>

20 - python中类常见的特殊属性及方法


obj.__dict__ 对象的属性字典 
obj.__class__ 对象所属的类 
class.__bases__ 类的基类元组(多继承) class.__base__ 类的基类 class.__mro__ 类层次结构 class.__subclasses__() 子类列表getattr(o,str) 获取类的摸一个方法isinstance(o,class) 判断对象是否是某个类的

21 - 重写__iter__、__next__实现迭代器


class Iterator_object:def __init__(self, lst):self.lst = lstself.index = 0        self.len = len(lst)def __iter__(self):return self    def __next__(self):if self.index <= self.len - 1:self.index += 1            return self.lst[self.index - 1]else:raise StopIteration

22- 创建一个生成器


def func1(i):
    print('数字是:' + str(i))
    return 2 * i

def func2():
    for i in range(10):
        print('第' + str(i) + '次')
        yield func1(i)
        print('完成')
# 或者 ss = (a[index] for index in range(3)) # 生成器推导式

if __name__ == '__main__':
    gene = func2()
    print(gene.__next__())

23 - 实现一个上下文管理器


class TestContext:

    def __enter__(self):
        print('执行上下文管理器的enter方法')
        return self # 必须有返回值

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('退出管理器')

    def get_name(self):
        print('ss')


if __name__ == '__main__':
    with TestContext() as f:
        f.get_name()

24- 继承threading.Thread实现多线程


import threading
import time

class MyThread(threading.Thread):

    def run(self):
        for i in range(0, 2):
            time.sleep(1)
            print(self.getName()+"运行了"+str(i+1)+"次")

def main():
    for i in range(1, 5):
        MyThread().start()


if __name__ == '__main__':
    main()
    print(threading.enumerate())

25 - 传入函数引用的方式


import threading
import time

my_lock = threading.Lock()
def func1(lst, d):
    count = 0
    for item in lst:
        count += item
    time.sleep(1)
    d[threading.current_thread().getName()] = count
    d['总数'] += d[threading.current_thread().getName()]


lst1 = [1, 2, 3, 4, 5, 6]
lst2 = [7, 2, 3, 4, 5, 6]
d = {'总数': 0}


if __name__ == '__main__':
    students = ['小红', '小明', '小绿', '小紫']
    threads = {}
    for item in students:
        if item == '小明' or item == '小紫':
            threads[item] = threading.Thread(target=func1, args=[lst2, d], name=item)
        else:
            threads[item] = threading.Thread(target=func1, args=[lst1, d], name=item)
    for student in threads:
        threads[student].start()
        threads[student].join()
    print(d['小红'])
    print(d['小明'])
    print(d['小绿'])
    print(d['小紫'])
    print(d['总数'])

26- 多线程死锁的产生(互相持有对方需要的锁)


import threading
import time


class MyThread(threading.Thread):

    my_lock1 = threading.Lock()
    my_lock2 = threading.Lock()

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

    def run(self):
        if self.name == "A":
            self.my_lock1.acquire()
            try:
                print("A线程先持有锁1")
                time.sleep(1)
                self.my_lock2.acquire()
                try:
                    print("A线程再持有锁2")
                except:
                    print("出现了异常")
                finally:
                    self.my_lock2.release()
            except:
                print("出现了异常")
            finally:
                self.my_lock1.release()
        else:
            self.my_lock2.acquire()
            try:
                print("B线程先持有锁2")
                time.sleep(1)
                self.my_lock1.acquire()
                try:
                    print("B线程再持有锁1")
                except:
                    print("出现了异常")
                finally:
                    self.my_lock1.release()
            except:
                print("出现了异常")
            finally:
                self.my_lock2.release()



if __name__ == '__main__':
    MyThread("A").start()
    MyThread("B").start()
// 输出结果
A线程先持有锁1
B线程先持有锁2

27 - 多线程死锁的产生(多次获取不可重入锁)


import threading
import time


class MyThread(threading.Thread):

    my_lock1 = threading.Lock()

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

    def run(self):
        self.my_lock1.acquire()
        try:
            print("A线程先持有锁1")
            time.sleep(1)
            self.my_lock1.acquire()
            try:
                print("A线程再持有锁1")
            except:
                print("出现了异常")
            finally:
                self.my_lock1.release()
        except:
            print("出现了异常")
        finally:
            self.my_lock1.release()


if __name__ == '__main__':
    MyThread("A").start()

28 - GIL(全局解释器锁)


  • 1. GIL是Cpython解释器中,保证python程序运行时,始终只有一个线程在执行,所以python多线程并不能充分利用CPU多核的优势。
    2. 为什么不对Cpython解释器做优化?
  • BDFL of Python的创始人Guido van Rossum在2007年09 月的文章It isn't Easy to Remove the GIL,大概是说,之前做过移除GIL的尝试,但是移除后,发现Cpython解释器的执行效率降低了很多,大过了利用多核的优势,另一方面,去除GIL会使模块的扩展变得很复杂,等等,同时,他也希望有人能够继续从事维护无GIL分支版本,贡献思路等等。

3. 多线程、多进程、协程之间的区别

  1. 多进程资源消耗比较大,但是可以利用多核优势,在计算密集型场景时适合使用。常用的库是(multiprocessing)
  2. 协程是协程间切换资源消耗最小,但是无法利用多核的优势,在IO密集型的场景下适合使用,可以做并发。常用的库有(asyncio、gevent),这两个库的区别是,gevent自动识别阻塞操作,asyncio是需要我们自己识别。
  3. 多线程介于多进程与协程之间。线程间切换消耗资源一般效率也一般。所以对于python来说。没上面两个实用。常用(Threading)

29 - python协程概念(面试用)


  1. 概念:协程也叫微线程\纤程,是一种用户态的轻量级线程,与线程的区别时,协程的调度时系统级别的调度,由系统决定,协程时程序级别的,根据我们自身需求,进行调度。
  2. python对协程的支持时通过yield关键字实现的(即生成器generator),既可以通过for循环调用,也可以通过内建函数next()获取返回值,通过生成器的send方法,传入值

30 - 采用yield实现生产者消费者模式


def consumer():
    while True:
        product = yield '开始消费'
        print('消费'+ product)


def productor(consumer):
    for i in range(0, 5):
        consumer.send('产品' + str(i+1))  # 向生成器传入参数,并消费


if __name__ == '__main__':
    print('创建生成器')
    g = consumer()
    print('用next方法第一次运行生成器,并打印返回结果')
    print(next(g)


运行结果
Connected to pydev debugger (build 182.4129.34)
创建生成器
用next方法第一次运行生成器,并打印返回结果
开始消费
消费产品1
消费产品2
消费产品3
消费产品4
消费产品5

31 - asyncio的简介


asyncio(python3自带的一个库)的编程模式是采用消息循环,主要用到以下方法或者关键字:

  • event_loop事件循环:创建一个无限循环,来执行一个或者一组协程
  • coroutine 协程:就是用async关键字声明的函数
  • task:是对协程对象的封装,会包含任务的各种状态。
  • future:代表没有执行的任务的结果,和task差不多。
  • async/await:async用户定义协程,await用户阻塞或者挂起协程。

32 - asyncio中使用await的例子


import asyncio
import time

async def work1():
    await asyncio.sleep(5)  # 当程序执行到这个位置会挂起该协程执行其他的
    print("第一个任务")


async def work2():
    await asyncio.sleep(5)
    print("第二个任务")


async def gather():
    await asyncio.gather(work1(), work2())

if __name__ == '__main__':
    start = time.time()
    loop = asyncio.get_event_loop()
    loop.run_until_complete(gather())
    end = time.time()
    print(start - end)


运行结果:
Connected to pydev debugger (build 182.4129.34)
第二个任务
第一个任务
-5.004826545715332

Process finished with exit code 0

33 - asyncio中创建task/future


import asyncio
import time

async def work1():
    await asyncio.sleep(5)
    print("第一个任务")


if __name__ == '__main__':
    start = time.time()
    loop = asyncio.get_event_loop()
    task1 = asyncio.ensure_future(work1())
    task2 = loop.create_task(work1())
    print('task1是否属于asyncio.Future:' + str(isinstance(task1, asyncio.Future)))
    print('task2是否属于asyncio.Future:' + str(isinstance(task2, asyncio.Future)))
    loop.run_until_complete(task1)
    end = time.time()
    print(start - end)
    print(task1)




运行结果
Connected to pydev debugger (build 182.4129.34)
task1是否属于asyncio.Future:True
task2是否属于asyncio.Future:True
第一个任务
第一个任务
-5.00496768951416
4> result=None>

34 -  asyncio中绑定回调,即处理结果(两种获取结果的方式)


import asyncio

async def work1():
    await asyncio.sleep(5)
    return '第一个任务完成了'


def callback(future):
    print("通过回调获取结果:"+future.result())


if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    task = loop.create_task(work1())
    task.add_done_callback(callback) # 通过回调获取结果
    loop.run_until_complete(task)
    print("通过result获取结果:"+task.result()) # 通过协程执行完毕获取结果




运行结果:
Connected to pydev debugger (build 182.4129.34)
通过回调获取结果:第一个任务完成了
通过result获取结果:第一个任务完成了

Process finished with exit code 0

35 -  使用协程创建并发(也可以采用协程的第一个例子)


import asyncio
import time

async def work1():
    await asyncio.sleep(5)
    return "第一个任务"


async def work2():
    await asyncio.sleep(5)
    return "第二个任务"


async def work3():
    await asyncio.sleep(5)
    return "第三个任务"


if __name__ == '__main__':
    start = time.time()
    loop = asyncio.get_event_loop()
    tasks = [loop.create_task(work1()), loop.create_task(work2()), loop.create_task(work3())]
    loop.run_until_complete(asyncio.wait(tasks))
    end = time.time()
    print(start - end)
    for item in tasks:
        print(item.result())



运行结果:
Connected to pydev debugger (build 182.4129.34)
-5.005037784576416
第一个任务
第二个任务
第三个任务

Process finished with exit code 0

36 -  多进程编程,采用multiprocessing库,与多线程编写方式相同不再举例。


end

python怎么判断一个变量是数字 python 判断变量存在_全局变量_06