Python获取当前操作系统版本

参考python包: import distutils.util

import os
import re
import sys


def get_platform():
    """Return a string that identifies the current platform.  This is used mainly to
    distinguish platform-specific build directories and platform-specific built
    distributions.  Typically includes the OS name and version and the
    architecture (as supplied by 'os.uname()'), although the exact information
    included depends on the OS; eg. on Linux, the kernel version isn't
    particularly important.

    Examples of returned values:
       linux-i586
       linux-alpha (?)
       solaris-2.6-sun4u

    Windows will return one of:
       win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc)
       win32 (all others - specifically, sys.platform is returned)

    For other non-POSIX platforms, currently just returns 'sys.platform'.

    """
    if os.name == 'nt':
        if 'amd64' in sys.version.lower():
            return 'win-amd64'
        return sys.platform

    # Set for cross builds explicitly
    if "_PYTHON_HOST_PLATFORM" in os.environ:
        return os.environ["_PYTHON_HOST_PLATFORM"]

    if os.name != "posix" or not hasattr(os, 'uname'):
        # XXX what about the architecture? NT is Intel or Alpha,
        # Mac OS is M68k or PPC, etc.
        return sys.platform

    # Try to distinguish various flavours of Unix

    (osname, host, release, version, machine) = os.uname()

    # Convert the OS name to lowercase, remove '/' characters, and translate
    # spaces (for "Power Macintosh")
    osname = osname.lower().replace('/', '')
    machine = machine.replace(' ', '_')
    machine = machine.replace('/', '-')

    if osname[:5] == "linux":
        # At least on Linux/Intel, 'machine' is the processor --
        # i386, etc.
        # XXX what about Alpha, SPARC, etc?
        return "%s-%s" % (osname, machine)
    elif osname[:5] == "sunos":
        if release[0] >= "5":  # SunOS 5 == Solaris 2
            osname = "solaris"
            release = "%d.%s" % (int(release[0]) - 3, release[2:])
            # We can't use "platform.architecture()[0]" because a
            # bootstrap problem. We use a dict to get an error
            # if some suspicious happens.
            bitness = {2147483647: "32bit", 9223372036854775807: "64bit"}
            machine += ".%s" % bitness[sys.maxsize]
        # fall through to standard osname-release-machine representation
    elif osname[:3] == "aix":
        return "%s-%s.%s" % (osname, version, release)
    elif osname[:6] == "cygwin":
        osname = "cygwin"
        rel_re = re.compile(r'[\d.]+', re.ASCII)
        m = rel_re.match(release)
        if m:
            release = m.group()
    elif osname[:6] == "darwin":
        import _osx_support, distutils.sysconfig
        osname, release, machine = _osx_support.get_platform_osx(
            distutils.sysconfig.get_config_vars(),
            osname, release, machine)

    return "%s-%s-%s" % (osname, release, machine)

 

0

[gongel] ImportError: attempted relative import with no known parent package

  • 目录结构
parent/
├── parent.py
└── son
    └── son.py
  • parent.py
value = 'parent'
  • son.py
from .. import parent

print('count = {}'.format(parent.value))
一. 问题复现

这时候运行son.py时会出现“ImportError: attempted relative import with no known parent package”

二. 解决办法

1.【最简洁】增加上层路径到sys.path中,修改son.py的内容为

import os
import sys

# Add parent.py to system path
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir)))

import parent

print('count = {}'.format(parent.value))

2. 增加上级目录,同时将下级的文件夹设置为package,修改后的目录结构为

grandfather/
├── grandfather.py
└── parent
    ├── __init__.py     # 里面为空
    ├── parent.py       # 内容保持不变
    └── son
        ├── __init__.py # 里面为空
        └── son.py      # 内容保持不变

grandfather.py

import parent.son.son

3. 【类似于2,不用grandfather.py】增加上级目录,同时将下级的文件夹设置为package,修改后的目录结构为

grandfather/
└── parent
    ├── __init__.py
    ├── parent.py
    └── son
        ├── __init__.py
        └── son.py

在grandfather目录下,通过以下命令调用:

python -m parent.son.son

Ref:https://napuzba.com/a/import-error-relative-no-parent

4+

Beam search

1.简单实现

import torch

# Beam  search
samples = []
topk = 10
log_prob, v_idx = decoder_outputs.detach().topk(topk)
for k in range(topk):
    samples.append([[v_idx[0][k].item()], log_prob[0][k], decoder_state])
for i in range(max_len):
    new_samples = []
    for sample in samples:
        v_list, score, decoder_state = sample
        if v_list[-1] == de_vocab.item2index['_EOS_']:
            new_samples.append([v_list, score, decoder_state])
            continue

        decoder_inputs = torch.LongTensor([v_list[-1]])
        decoder_outputs, new_states = decoder(decoder_inputs, encoder_output, decoder_state)
        log_prob, v_idx = decoder_outputs.data.topk(topk)

        for k in range(topk):
            new_v_list = []
            new_v_list += v_list + [v_idx[0][k].item()]
            new_samples.append([new_v_list, score + log_prob[0][k], new_states])

    new_samples = sorted(new_samples, key=lambda sample: sample[1], reverse=True)
    samples = new_samples[:topk]
    
v_list, score, states = samples[0]
for v_idx in v_list:
    pred_sent.append(de_vocab.index2item[v_idx])

2.transformers实现

0

Python赋值/浅/深拷贝

一、可变对象和不可变对象

  • 可变对象,该对象所指向的内存中的值可以被改变。变量(准确的说是引用)改变后,实际上是其所指的值直接发生改变,并没有发生复制行为,也没有开辟新的出地址,通俗点说就是原地改变。比如列表list字典dict集合set
  • 不可变对象,该对象所指向的内存中的值不能被改变。当改变某个变量时候,由于其所指的值不能被改变,相当于把原来的值复制一份后再改变,这会开辟一个新的地址,变量再指向这个新的地址。比如数值类型(int和float)字符串str元组tuple

二、赋值、浅拷贝、深拷贝

1. 赋值

1.1可变对象

a=b=obj 两者在内存中地址一致,并且子元素在内存的地址也一致,所以修改其中一个对象的值,另外一个对象的值肯定也会修改。

1.2 不可变对象

1.2.1 在缓存范围内

只要是某个定值(整型、浮点型、或者字符串),复制给任何对象,所指向的内存地址都是一致的。

1.2.2 不在缓存范围内

某个定值超过缓存范围,比如字符串过长、整型过大,会出现指向该定值的两个对象的内存地址不一致的情况。

2. 浅拷贝

  • 使用copy()函数 from copy import copy
  • 使用切片操作
  • 使用工厂函数(如list/dir/set)

2.1 可变对象

a=copy(b) a和b的内存地址不一致,但是子元素的内存地址都一致。如果b的子元素为不可变对象,那么修改任何一个对象中的该子元素,不会引起另一个对象的该子元素的改变;如果b的子元素为可变对象,那么修改任何一个对象中的该子元素,则会引起另一个对象相应的改变。(其实对子元素的修改就相当于赋值)。

2.2 不可变对象

相当于赋值。

3. 深拷贝

  • from copy import deepcopy

3.1 可变对象

a=deepcopy(b) a和b的内存地址不一致。如果子元素为不可变对象,那么深拷贝后内存地址也不一致,所以修改不会相互影响 ;如果子元素为可变对象,那么深拷贝后内存地址是一致的,但是修改也不会相互影响,具体参考不可变对象的赋值。

3.2 不可变对象

相当于赋值。

三、参考

0