百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

python中也有隐藏彩蛋,你知道吗?

bigegpt 2024-09-09 01:22 7 浏览

可否带我飞?

import antigravity
  • antigravity 模块是 Python 开发人员发布的少数复活节彩蛋之一.
  • import antigravity 会打开一个 Python 的经典 XKCD 漫画页面.
  • 不止如此. 这个复活节彩蛋里还有一个复活节彩蛋. 如果你看一下代码, 就会发现还有一个函数实现了 XKCD's geohashing 算法.
  • 连Python也知道爱是难言的

    import this

    执行这句会发生什么?

    The Zen of Python, by Tim Peters
    
    Beautiful is better than ugly.
    Explicit is better than implicit.
    Simple is better than complex.
    Complex is better than complicated.
    Flat is better than nested.
    Sparse is better than dense.
    Readability counts.
    Special cases ,aren't special enough to break the rules.
    Although practicality beats purity.
    Errors should never pass silently.
    Unless explicitly silenced.
    In the face of ambiguity, refuse the temptation to guess.
    There should be one-- and preferably only one --obvious way to do it.
    Although that way may not be obvious at first unless you're Dutch.
    Now is better than never.
    Although never is often better than *right* now.
    If the implementation is hard to explain, it's a bad idea.
    If the implementation is easy to explain, it may be a good idea.
    Namespaces are one honking great idea -- let's do more of those!
    
    Process finished with exit code 0

    这又是一个复活节彩蛋,实际它的源码就一个py文件,打印了这些信息,然后什么都没干

    else无处不在

    在Python里else已经不局限在if判断里了,它出现在众多逻辑处理中

    • for......else......
    def does_exists_num(l, to_find):
        for num in l:
            if num == to_find:
                print("Exists!")
                break
        else:
            print("Does not exist")
    
    some_list = [1, 2, 3, 4, 5]
    does_exists_num(some_list, 4)
    # 输出:Exists!
    does_exists_num(some_list, -1)
    # 输出:Does not exist

    当for循环中执行了break,就不会执行else下的语句,要注意continue不会受此影响

    try:
        pass
    except:
        print("Exception occurred!!!")
    else:
        print("Try block executed successfully...")
    
    # 输出:Try block executed successfully...

    同样的不出现异常的时候,执行else语句

    私有不私有?

    class Yo(object):
        def __init__(self):
            self.__honey = True
            self.bitch = True
    
    Yo().bitch
    # 输出:True
    Yo().__honey
    # AttributeError: 'Yo' object has no attribute '__honey'
    Yo()._Yo__honey
    # 输出:True

    双下划线私有变量如何完成私有变量特性的?实际是python解释器默认把双下划线开头的变量重命名了,命名方式为:_类名__varname

    更快的 +=

    import timeit
    # 用 "+" 连接三个字符串:
    print(timeit.timeit("s1 = s1 + s2 + s3", setup="s1 = ' ' * 100000; s2 = ' ' * 100000; s3 = ' ' * 100000", number=100))
    # 输出:0.5473556190000001
    
    # 用 "+=" 连接三个字符串:
    print(timeit.timeit("s1 += s2 + s3", setup="s1 = ' ' * 100000; s2 = ' ' * 100000; s3 = ' ' * 100000", number=100))
    # 输出:0.012764710999999984

    连接两个以上的字符串时 += 比 + 更快, 因为在计算过程中第一个字符串 (例如, s1 += s2 + s3 中的 s1) 不会被销毁,就是 += 执行的是追加操作,少了一个销毁新建的动作。

    来做个巨大的字符串吧!

    def add_string_with_plus(iters):
        s = ""
        for i in range(iters):
            s += "xyz"
        assert len(s) == 3*iters
    
    def add_bytes_with_plus(iters):
        s = b""
        for i in range(iters):
            s += b"xyz"
        assert len(s) == 3*iters
    
    def add_string_with_format(iters):
        fs = "{}"*iters
        s = fs.format(*(["xyz"]*iters))
        assert len(s) == 3*iters
    
    def add_string_with_join(iters):
        l = []
        for i in range(iters):
            l.append("xyz")
        s = "".join(l)
        assert len(s) == 3*iters
    
    def convert_list_to_string(l, iters):
        s = "".join(l)
        assert len(s) == 3*iters
    
    print(timeit(add_string_with_plus(10000)))
    # 输出:1000 loops, best of 3: 972 μs per loop
    
    print(timeit(add_bytes_with_plus(10000)))
    # 输出:1000 loops, best of 3: 815 μs per loop
    
    print(timeit(add_string_with_format(10000)))
    # 输出:1000 loops, best of 3: 508 μs per loop
    
    print(timeit(add_string_with_join(10000)))
    # 输出:1000 loops, best of 3: 878 μs per loop
    
    l = ["xyz"] * 10000
    print(timeit(convert_list_to_string(l, 10000)))
    # 输出:10000 loops, best of 3: 80 μs per loop
    
    # 我们将迭代次数增加10倍.
    print(timeit(add_string_with_plus(100000))) # 执行时间线性增加
    # 输出: 100 loops, best of 3: 9.75 ms per loop
    print(timeit(add_bytes_with_plus(100000))) # 二次增加
    # 输出:1000 loops, best of 3: 974 ms per loop
    print(timeit(add_string_with_format(100000))) # 线性增加
    # 输出:100 loops, best of 3: 5.25 ms per loop
    print(timeit(add_string_with_join(100000))) # 线性增加
    # 输出:100 loops, best of 3: 9.85 ms per loop
    l = ["xyz"]*100000
    print(timeit(convert_list_to_string(l, 100000))) # 线性增加
    # 输出:1000 loops, best of 3: 723 μs per loop
  • 不要用 + 去生成过长的字符串, 在 Python 中, str 是不可变得, 所以在每次连接中你都要把左右两个字符串复制到新的字符串中. 如果你连接四个长度为10的字符串, 你需要拷贝 (10+10) + ((10+10)+10) + (((10+10)+10)+10) = 90 个字符而不是 40 个字符. 随着字符串的数量和大小的增加, 情况会变得越发的糟糕 (就像add_bytes_with_plus 函数的执行时间一样)
  • 更建议使用 .format. 或 % 语法 ,但是对于短字符串, 它们比 + 稍慢一点.
  • 如果你所需的内容已经以可迭代对象的形式提供了, 使用 ''.join(可迭代对象) 要快多了.
  • add_string_with_plus 的执行时间没有像 add_bytes_with_plus 一样出现二次增加是因为解释器会如同上一个列子所讨论的一样优化 +=. 用 s = s + "x" + "y" + "z" 替代 s += "xyz" 的话, 执行时间就会二次增加了.
  • def add_string_with_plus(iters):
        s = ""
        for i in range(iters):
            s = s + "x" + "y" + "z"
        assert len(s) == 3*iters
    
    print(timeit(add_string_with_plus(10000)))
    # 输出:100 loops, best of 3: 9.87 ms per loop
    print(timeit(add_string_with_plus(100000))) # 执行时间二次增加
    # 输出:1 loops, best of 3: 1.09 s per loop

    [] = ()

    看着奇怪但能正确运行的语句,语句在语义上是正确的 (解包一个空的 tuple 并赋值给 list)'a'[0][0][0][0][0] 在语义上也是正确的, 因为在 Python 中字符串同时也是序列(可迭代对象支持使用整数索引访问元素).

    ++和--运算符

    a = 5
    print(a)
    # 输出:5 
    print(++a)
    # 输出:5 
    print(--a)
    # 输出:5

    注意python 里没有 ++ 操作符. 这其实是两个 + 操作符.++a 被解析为 +(+a) 最后等于 a. --a 同理.

    本地变量数量

    Python 使用 2个字节存储函数中的本地变量.

    理论上, 这意味着函数中只能定义65536个变量. 但是,Python 内置了一个方便的解决方案,可用于存储超过2^16个变量名. 下面的代码演示了当定义了超过65536个局部变量时堆栈中发生的情况

    import dis
    exec("""
    def f():
        """ + """
        """.join(["X"+str(x)+"=" + str(x) for x in range(65539)]))
    
    f()
    
    print(dis.dis(f))

    'abc'.count('') == 4

    print('abc'.count('') == 4)
    # 输出:True

    下面这个方法能更好的说明问题

    def count(s, sub):
        result = 0
        for i in range(len(s) + 1 - len(sub)):
            result += (s[i:i + len(sub)] == sub)
        return result

    这个行为是由于空子串('')与原始字符串中长度为0的切片相匹配导致的.

    相关推荐

    Java 泛型大揭秘:类型参数、通配符与最佳实践

    引言在编程世界中,代码的可重用性和可维护性是至关重要的。为了实现这些目标,Java5引入了一种名为泛型(Generics)的强大功能。本文将详细介绍Java泛型的概念、优势和局限性,以及如何在...

    K8s 的标签与选择器:流畅运维的秘诀

    在Kubernetes的世界里,**标签(Label)和选择器(Selector)**并不是最炫酷的技术,但却是贯穿整个集群管理与运维流程的核心机制。正是它们让复杂的资源调度、查询、自动化运维变得...

    哈希Hash算法:原理、应用(哈希算法 知乎)

    原作者:Linux教程,原文地址:「链接」什么是哈希算法?哈希算法(HashAlgorithm),又称为散列算法或杂凑算法,是一种将任意长度的数据输入转换为固定长度输出值的数学函数。其输出结果通常被...

    C#学习:基于LLM的简历评估程序(c# 简历)

    前言在pocketflow的例子中看到了一个基于LLM的简历评估程序的例子,感觉还挺好玩的,为了练习一下C#,我最近使用C#重写了一个。准备不同的简历:image-20250528183949844查...

    55顺位,砍41+14+3!季后赛也成得分王,难道他也是一名球星?

    雷霆队最不可思议的新星:一个55号秀的疯狂逆袭!你是不是也觉得NBA最底层的55号秀,就只能当饮水机管理员?今年的55号秀阿龙·威金斯恐怕要打破你的认知了!常规赛阶段,这位二轮秀就像开了窍的天才,直接...

    5分钟读懂C#字典对象(c# 字典获取值)

    什么是字典对象在C#中,使用Dictionary类来管理由键值对组成的集合,这类集合被称为字典。字典最大的特点就是能够根据键来快速查找集合中的值,其键的定义不能重复,具有唯一性,相当于数组索引值,字典...

    c#窗体传值(c# 跨窗体传递数据)

    在WinForm编程中我们经常需要进行俩个窗体间的传值。下面我给出了两种方法,来实现传值一、在输入数据的界面中定义一个属性,供接受数据的窗体使用1、子窗体usingSystem;usingSyst...

    C#入门篇章—委托(c#委托的理解)

    C#委托1.委托的定义和使用委托的作用:如果要把方法作为函数来进行传递的话,就要用到委托。委托是一个类型,这个类型可以赋值一个方法的引用。C#的委托通过delegate关键字来声明。声明委托的...

    C#.NET in、out、ref详解(c#.net framework)

    简介在C#中,in、ref和out是用于修改方法参数传递方式的关键字,它们决定了参数是按值传递还是按引用传递,以及参数是否必须在传递前初始化。基本语义对比修饰符传递方式可读写性必须初始化调用...

    C#广义表(广义表headtail)

    在C#中,广义表(GeneralizedList)是一种特殊的数据结构,它是线性表的推广。广义表可以包含单个元素(称为原子),也可以包含另一个广义表(称为子表)。以下是一个简单的C#广义表示例代...

    「C#.NET 拾遗补漏」04:你必须知道的反射

    阅读本文大概需要3分钟。通常,反射用于动态获取对象的类型、属性和方法等信息。今天带你玩转反射,来汇总一下反射的各种常见操作,捡漏看看有没有你不知道的。获取类型的成员Type类的GetMembe...

    C#启动外部程序的问题(c#怎么启动)

    IT&OT的深度融合是智能制造的基石。本公众号将聚焦于PLC编程与上位机开发。除理论知识外,也会结合我们团队在开发过程中遇到的具体问题介绍一些项目经验。在使用C#开发上位机时,有时会需要启动外部的一些...

    全网最狠C#面试拷问:这20道题没答出来,别说你懂.NET!

    在竞争激烈的C#开发岗位求职过程中,面试是必经的一道关卡。而一场高质量的面试,不仅能筛选出真正掌握C#和.NET技术精髓的人才,也能让求职者对自身技术水平有更清晰的认知。今天,就为大家精心准备了20道...

    C#匿名方法(c#匿名方法与匿名类)

    C#中的匿名方法是一种没有名称只有主体的方法,它提供了一种传递代码块作为委托参数的技术。以下是关于C#匿名方法的一些重要特点和用法:特点省略参数列表:使用匿名方法可省略参数列表,这意味着匿名方法...

    C# Windows窗体(.Net Framework)知识总结

    Windows窗体可大致分为Form窗体和MDI窗体,Form窗体没什么好细说的,知识点总结都在思维导图里面了,下文将围绕MDI窗体来讲述。MDI(MultipleDocumentInterfac...