私信  •  关注

Aaron Hall

Aaron Hall 最近创建的主题
Aaron Hall 最近回复了
6 年前
回复了 Aaron Hall 创建的主题 » 在Python中执行数学运算时从列表中排除字符串[重复]

如何确定Python中的变量类型?

因此,如果您有一个变量,例如:

one = 1

你想知道它的类型吗?

在Python中,做任何事情都有正确的方法和错误的方法。这是正确的方法:

使用 type

>>> type(one)
<type 'int'>

你可以使用 __name__ 属性获取对象的名称。(这是需要使用 __dunder__ 要到达的名称-在 inspect 模块)

>>> type(one).__name__
'int'

不使用 __class__

在Python中,以下划线开头的名称在语义上不是公共API的一部分,用户最好避免使用它们。 (除非绝对必要。)

自从 类型 给我们对象的类,我们应该避免直接得到它。:

>>> one.__class__

这通常是人们在访问方法中的对象类型时的第一个想法——他们已经在寻找属性,所以类型看起来很奇怪。例如:

class Foo(object):
    def foo(self):
        self.__class__

不要。相反,请键入(self):

class Foo(object):
    def foo(self):
        type(self)

int和float的实现细节

如何查看变量的类型(无论是无符号32位、有符号16位等)。?

在Python中,这些细节是实现细节。所以,一般来说,我们在Python中通常不担心这个问题。不过,为了满足你的好奇心。。。

在Python 2中,int通常是一个有符号整数,等于实现的 word 宽度(受系统限制)。它通常被实现为 long in C . 当整数大于这个值时,我们通常将它们转换为Python long(具有无限精度,不要与C long混淆)。

例如,在32位Python 2中,我们可以推断int是有符号的32位整数:

>>> import sys

>>> format(sys.maxint, '032b')
'01111111111111111111111111111111'
>>> format(-sys.maxint - 1, '032b') # minimum value, see docs.
'-10000000000000000000000000000000'

在Python 3中,旧的int消失了,我们只使用(Python的)long as int unlimited precision.

我们还可以获得一些关于Python浮动的信息,这些浮动通常被实现为 double 在C中:

>>> sys.float_info
sys.floatinfo(max=1.7976931348623157e+308, max_exp=1024, max_10_exp=308, 
min=2.2250738585072014e-308, min_exp=-1021, min_10_exp=-307, dig=15, 
mant_dig=53, epsilon=2.2204460492503131e-16, radix=2, rounds=1)

结论

不使用 __阶级__ ,一个语义上非公共的API,用于获取变量的类型。使用 类型 相反。

不要太担心Python的实现细节。我不需要自己处理这个问题。你可能也不会,如果你真的这样做了,你应该知道足够多,不要指望这个答案做什么。

6 年前
回复了 Aaron Hall 创建的主题 » 如何使用uu name_uuuu==”uuuu main_uuu“来编写python脚本[副本]

什么是 if __name__ == "__main__": 是吗?

概述基本知识:

  • 全局变量, __name__ ,在作为程序入口点的模块中,是 '__main__' . 否则,它就是导入模块的名称。

  • 所以,在 if 只有当模块是程序的入口点时,块才会运行。

  • 它允许其他模块导入模块中的代码,而不必在导入时执行下面的代码块。


为什么我们需要这个?

开发和测试代码

假设您正在编写一个设计为用作模块的Python脚本:

def do_important():
    """This function does something very important"""

能够 通过将此函数调用添加到底部来测试模块:

do_important()

运行它(在命令提示符下)的方法如下:

~$ python important.py

问题

但是,如果要将模块导入到另一个脚本:

import important

在导入时 do_important 函数将被调用,因此您可能会注释掉函数调用, do_important() ,在底部。

# do_important() # I must remember to uncomment to execute this!

然后你必须记住你是否已经注释掉了你的测试函数调用这种额外的复杂性意味着你可能会忘记,使你的开发过程更加麻烦。

更好的方法

这个 __姓名__ 变量指向当前Python解释器所在的名称空间。

在导入的模块中,它是该模块的名称。

但是在主模块(或交互式Python会话,即解释器的Read、Eval、Print Loop或REPL)中,您正在运行 "__main__" .

因此,如果在执行之前检查:

if __name__ == "__main__":
    do_important()

使用上面的代码,您的代码将只在作为主模块运行时执行(或者故意从另一个脚本调用它)。

更好的方法

不过,有一种蟒蛇式的方法可以改进这一点。

如果我们想从模块外部运行这个业务流程呢?

如果我们在开发和测试这样一个函数时将要执行的代码放在这样一个函数中,然后检查 '''.''Mi'Ny'' 紧接着:

def main():
    """business logic for when running this module as the primary one!"""
    setup()
    foo = do_important()
    bar = do_even_more_important(foo)
    for baz in bar:
        do_super_important(baz)
    teardown()

# Here's our payoff idiom!
if __name__ == '__main__':
    main()

现在,我们有一个模块末尾的final函数,如果我们将该模块作为主模块运行,它将运行。

它将允许在不运行 main 函数,还将允许在从不同的 '''.''Mi'Ny'' 模块,即。

import important
important.main()

This idiom can also be found in the Python documentation in an explanation of the __main__ module. 该文本指出:

此模块表示(否则为匿名)作用域,其中 解释器的主程序执行从 标准输入、来自脚本文件或来自交互提示。它 在这种环境中 使脚本运行:

if __name__ == '__main__':
    main()
6 年前
回复了 Aaron Hall 创建的主题 » 在python3中如何将单词向后翻转?在这种情况下[副本]

为字符串实现反向函数的最佳方法是什么?

我自己在这个问题上的经验是学术性的。不过,如果你是一个专业人士,想快速找到答案,可以使用 -1 :

>>> 'a string'[::-1]
'gnirts a'

或者更容易理解(但由于方法名查找和给定迭代器时join形成列表的事实,速度较慢)。 str.join :

>>> ''.join(reversed('a string'))
'gnirts a'

或者为了可读性和可重用性,将切片放在函数中

def reversed_string(a_string):
    return a_string[::-1]

然后:

>>> reversed_string('a_string')
'gnirts_a'

更长的解释

如果你对学术博览会感兴趣,请继续阅读。

python的str对象中没有内置的reverse函数。

下面是一些关于python字符串的信息,您应该知道:

  1. 在蟒蛇中, 字符串是不可变的 . 更改字符串不会修改字符串。它创造了一个新的。

  2. 字符串是可切片的。对字符串进行切片可以按给定的增量从字符串中的一个点向后或向前到另一个点生成一个新字符串。它们采用切片符号或下标中的切片对象:

    string[subscript]
    

下标通过在大括号中包含冒号来创建切片:

    string[start:stop:step]

要在大括号外创建切片,需要创建切片对象:

    slice_obj = slice(start, stop, step)
    string[slice_obj]

可读的方法:

同时 ''.join(reversed('foo')) 是可读的,它需要调用字符串方法, 斯特朗加盟 ,在另一个被调用的函数上,这可能相对较慢。让我们把这个放在函数中-我们再回到它:

def reverse_string_readable_answer(string):
    return ''.join(reversed(string))

最有效的方法:

使用反向切片要快得多:

'foo'[::-1]

但是,对于不太熟悉切片或原始作者意图的人来说,我们如何才能使其更具可读性和可理解性呢?让我们在下标符号之外创建一个slice对象,给它一个描述性名称,并将其传递给下标符号。

start = stop = None
step = -1
reverse_slice = slice(start, stop, step)
'foo'[reverse_slice]

作为功能实现

要实际将其作为函数实现,我认为它在语义上足够清晰,只需使用一个描述性名称即可:

定义反转字符串(字符串):
返回一个字符串[::-1]

用法很简单:

reversed_string('foo')

你的老师可能想要:

如果你有一个教练,他们可能希望你从一个空字符串开始,并从旧字符串建立一个新字符串。可以使用while循环使用纯语法和文本来完成此操作:

def reverse_a_string_slowly(a_string):
    new_string = ''
    index = len(a_string)
    while index:
        index -= 1                    # index = index - 1
        new_string += a_string[index] # new_string = new_string + character
    return new_string

这在理论上是不好的,因为,记住, 字符串是不可变的 -所以每次你把一个字符附加到 new_string ,理论上每次都会创建一个新字符串!然而,cpython知道如何在某些情况下优化它,这一小情况就是其中之一。

最佳实践

理论上更好的做法是收集列表中的子字符串,稍后再将其加入:

def reverse_a_string_more_slowly(a_string):
    new_strings = []
    index = len(a_string)
    while index:
        index -= 1                       
        new_strings.append(a_string[index])
    return ''.join(new_strings)

但是,正如我们将在下面的cpython计时中看到的,这实际上需要更长的时间,因为cpython可以优化字符串连接。

计时

以下是时间安排:

>>> a_string = 'amanaplanacanalpanama' * 10
>>> min(timeit.repeat(lambda: reverse_string_readable_answer(a_string)))
10.38789987564087
>>> min(timeit.repeat(lambda: reversed_string(a_string)))
0.6622700691223145
>>> min(timeit.repeat(lambda: reverse_a_string_slowly(a_string)))
25.756799936294556
>>> min(timeit.repeat(lambda: reverse_a_string_more_slowly(a_string)))
38.73570013046265

cpython优化字符串连接,而其他实现 may not :

…不要依赖于cpython对a+=b或a=a+b形式的语句的就地字符串连接的有效实现。这种优化即使在cpython中也很脆弱(它只适用于某些类型),而且在不使用refcounting的实现中根本不存在。在库的性能敏感部分中,应改用“”join()形式。这将确保在不同实现之间以线性时间进行连接。

8 年前
回复了 Aaron Hall 创建的主题 » 强制退出运行python中的线程[duplicate]

这是个错误的答案,请看评论

以下是操作方法:

from threading import *

...

for thread in enumerate():
    if thread.isAlive():
        try:
            thread._Thread__stop()
        except:
            print(str(thread.getName()) + ' could not be terminated'))

给它几秒钟,然后你的线程应该停止。同时检查 thread._Thread__delete() 方法。

我建议你 thread.quit() 方便的方法。例如,如果您的线程中有一个套接字,我建议您创建一个 quit() 方法,终止套接字,然后运行 thread._Thread__stop() 在你的内心 {)