文档章节

编写兼容 Python 2 和 Python 3 的代码

舒运
 舒运
发布于 2017/06/12 15:34
字数 3066
阅读 14
收藏 1
点赞 0
评论 0

该笔记向你展示了编写不会过时的兼容 Python 2 和 Python 3 的代码风格。

它是 Ed Schofield 在 PyCon AU 2014 的演讲,“ Writing 2/3 compatible code ”。

最低版本:

  • Python 2: 2.6+
  • Python 3: 3.3+

安装

一些下面的 imports 适用于使用 pip 安装在 PyPI 上安装:

import future        # pip install future
import past          # pip install past
import six           # pip install six

以下的脚本也适用于 pip 安装:

futurize             # pip install futurize
pasteurize           # pip install pasteurize

查看 http://python-future.org 和 https://pythonhosted.org/six/ 获取更多消息。

基本语法差异

print

# Python 2 only:
print 'Hello'
# Python 2 and 3:
print('Hello')

为了打印出多个 strings。 import print_function 来防止 Py2 把它解释成一个元组。

# Python 2 only:
print 'Hello', 'Guido'
# Python 2 and 3:
from __future__ import print_function    # (at top of module)

print('Hello', 'Guido')
# Python 2 only:
print >> sys.stderr, 'Hello'
# Python 2 and 3:
from __future__ import print_function

print('Hello', file=sys.stderr)
# Python 2 only:
print 'Hello',
# Python 2 and 3:
from __future__ import print_function

print('Hello', end='')

抛出异常

# Python 2 only:
raise ValueError, "dodgy value"
# Python 2 and 3:
raise ValueError("dodgy value")

使用 traceback 抛出异常:

# Python 2 only:
traceback = sys.exc_info()[2]
raise ValueError, "dodgy value", traceback
# Python 3 only:
raise ValueError("dodgy value").with_traceback()
# Python 2 and 3: option 1
from six import reraise as raise_
# or
from future.utils import raise_

traceback = sys.exc_info()[2]
raise_(ValueError, "dodgy value", traceback)
# Python 2 and 3: option 2
from future.utils import raise_with_traceback

raise_with_traceback(ValueError("dodgy value"))

异常链 (PEP 3134):

# Setup:
class DatabaseError(Exception):
    pass
# Python 3 only
class FileDatabase:
    def __init__(self, filename):
        try:
            self.file = open(filename)
        except IOError as exc:
            raise DatabaseError('failed to open') from exc
# Python 2 and 3:
from future.utils import raise_from

class FileDatabase:
    def __init__(self, filename):
        try:
            self.file = open(filename)
        except IOError as exc:
            raise_from(DatabaseError('failed to open'), exc)
# Testing the above:
try:
    fd = FileDatabase('non_existent_file.txt')
except Exception as e:
    assert isinstance(e.__cause__, IOError)    # FileNotFoundError on Py3.3+ inherits from IOError

捕获异常

# Python 2 only:
try:
    ...
except ValueError, e:
    ...
# Python 2 and 3:
try:
    ...
except ValueError as e:
    ...

除法

整除(rounding down):

# Python 2 only:
assert 2 / 3 == 0
# Python 2 and 3:
assert 2 // 3 == 0

“True division” (float division):

# Python 3 only:
assert 3 / 2 == 1.5
# Python 2 and 3:
from __future__ import division    # (at top of module)

assert 3 / 2 == 1.5

“Old division” (i.e. compatible with Py2 behaviour):

# Python 2 only:
a = b / c            # with any types
# Python 2 and 3:
from past.utils import old_div

a = old_div(b, c)    # always same as / on Py2

长整数

短整数在 Python 3 中已经去除了,并且 long 已经变成了 int(没有 L 在 repr 后面)

# Python 2 only
k = 9223372036854775808L

# Python 2 and 3:
k = 9223372036854775808
# Python 2 only
bigint = 1L

# Python 2 and 3
from future.builtins import int
bigint = int(1)

为了测试一个值是否是整数(任何类型):

# Python 2 only:
if isinstance(x, (int, long)):
    ...

# Python 3 only:
if isinstance(x, int):
    ...

# Python 2 and 3: option 1
from future.builtins import int    # subclass of long on Py2

if isinstance(x, int):             # matches both int and long on Py2
    ...

# Python 2 and 3: option 2
from past.builtins import long

if isinstance(x, (int, long)):
    ...

八进制常量

0644     # Python 2 only
0o644    # Python 2 and 3

Backtick repr

`x`      # Python 2 only
repr(x)  # Python 2 and 3

元类

class BaseForm(object):
    pass

class FormType(type):
    pass
# Python 2 only:
class Form(BaseForm):
    __metaclass__ = FormType
    pass
# Python 3 only:
class Form(BaseForm, metaclass=FormType):
    pass
# Python 2 and 3:
from six import with_metaclass
# or
from future.utils import with_metaclass

class Form(with_metaclass(FormType, BaseForm)):
    pass

Strings 和 bytes

Unicode(text) 字符字面量

如果你更新一个已经存在的 Python 2 的代码库,为所有的字符字面量使用 u 做前缀作为 unicode 的标记可能会更好。

# Python 2 only
s1 = 'The Zen of Python'
s2 = u'きたないのよりきれいな方がいい\n'

# Python 2 and 3
s1 = u'The Zen of Python'
s2 = u'きたないのよりきれいな方がいい\n'

futurize 和 python-modernize 工具没有提供一个选项自动完成这个。

如果你为了个项目编写新的代码库,你可以用一个 unicode 字符模块标记所有的字符字面量。

# Python 2 and 3
from __future__ import unicode_literals    # at top of module

s1 = 'The Zen of Python'
s2 = 'きたないのよりきれいな方がいい\n'

查看 http://python-future.org/unicode_literals.html 这里获取更多的关于讨论使用哪种风格的讨论。

字节-字符 字面量

# Python 2 only
s = 'This must be a byte-string'

# Python 2 and 3
s = b'This must be a byte-string'

To loop over a byte-string with possible high-bit characters, obtaining each character as a byte-string of length 1:

# Python 2 only:
for bytechar in 'byte-string with high-bit chars like \xf9':
    ...

# Python 3 only:
for myint in b'byte-string with high-bit chars like \xf9':
    bytechar = bytes([myint])

# Python 2 and 3:
from future.builtins import bytes
for myint in bytes(b'byte-string with high-bit chars like \xf9'):
    bytechar = bytes([myint])

chr() 和 .encode('latin-1') 其中的任何一个都可以用于把一个 int 转换成一个 1-char byte string

# Python 3 only:
for myint in b'byte-string with high-bit chars like \xf9':
    char = chr(myint)    # returns a unicode string
    bytechar = char.encode('latin-1')

# Python 2 and 3:
from future.builtins import bytes, chr
for myint in bytes(b'byte-string with high-bit chars like \xf9'):
    char = chr(myint)    # returns a unicode string
    bytechar = char.encode('latin-1')    # forces returning a byte str

basestring

# Python 2 only:
a = u'abc'
b = 'def'
assert (isinstance(a, basestring) and isinstance(b, basestring))

# Python 2 and 3: alternative 1
from past.builtins import basestring    # pip install future

a = u'abc'
b = b'def'
assert (isinstance(a, basestring) and isinstance(b, basestring))
# Python 2 and 3: alternative 2: refactor the code to avoid considering
# byte-strings as strings.

from future.builtins import str
a = u'abc'
b = b'def'
c = b.decode()
assert isinstance(a, str) and isinstance(c, str)
# ...

unicode

# Python 2 only:
templates = [u"blog/blog_post_detail_%s.html" % unicode(slug)]
# Python 2 and 3: alternative 1
from future.builtins import str
templates = [u"blog/blog_post_detail_%s.html" % str(slug)]
# Python 2 and 3: alternative 2
from future.builtins import str as text
templates = [u"blog/blog_post_detail_%s.html" % text(slug)]

StringIO

# Python 2 only:
from StringIO import StringIO
# or:
from cStringIO import StringIO

# Python 2 and 3:
from io import BytesIO     # for handling byte strings
from io import StringIO    # for handling unicode strings

Imports relative to a package

假设包的结构是这样的:

mypackage/
    __init__.py
    submodule1.py
    submodule2.py

submodule1.py 的代码如下:

# Python 2 only:
import submodule2
# Python 2 and 3:
from . import submodule2
# Python 2 and 3:
# To make Py2 code safer (more like Py3) by preventing
# implicit relative imports, you can also add this to the top:
from __future__ import absolute_import

字典

heights = {'Fred': 175, 'Anne': 166, 'Joe': 192}

Iterating through dict keys/values/items

迭代字典的键:

# Python 2 only:
for key in heights.iterkeys():
    ...
# Python 2 and 3:
for key in heights:
    ...

迭代字典的值:

# Python 2 only:
for value in heights.itervalues():
    ...
# Idiomatic Python 3
for value in heights.values():    # extra memory overhead on Py2
    ...
# Python 2 and 3: option 1
from future.builtins import dict

heights = dict(Fred=175, Anne=166, Joe=192)
for key in heights.values():    # efficient on Py2 and Py3
    ...
# Python 2 and 3: option 2
from future.builtins import itervalues
# or
from six import itervalues

for key in itervalues(heights):
    ...

迭代字典元素:

# Python 2 only:
for (key, value) in heights.iteritems():
    ...
# Python 2 and 3: option 1
for (key, value) in heights.items():    # inefficient on Py2
    ...
# Python 2 and 3: option 2
from future.builtins import iteritems
# or
from six import iteritems

for (key, value) in iteritems(heights):
    ...

字典的键/值/元素 作为一个列表

字典的键作为一个列表:

# Python 2 only:
keylist = heights.keys()
assert isinstance(keylist, list)
# Python 2 and 3:
keylist = list(heights)
assert isinstance(keylist, list)

字典的值作为一个列表:

# Python 2 only:
heights = {'Fred': 175, 'Anne': 166, 'Joe': 192}
valuelist = heights.values()
assert isinstance(valuelist, list)
# Python 2 and 3: option 1
valuelist = list(heights.values())    # inefficient on Py2
# Python 2 and 3: option 2
from future.builtins import dict

heights = dict(Fred=175, Anne=166, Joe=192)
valuelist = list(heights.values())
# Python 2 and 3: option 3
from future.utils import listvalues

valuelist = listvalues(heights)
# Python 2 and 3: option 4
from future.utils import itervalues
# or
from six import itervalues

valuelist = list(itervalues(heights))

字典元素作为一个列表:

# Python 2 and 3: option 1
itemlist = list(heights.items())    # inefficient on Py2
# Python 2 and 3: option 2
from future.utils import listitems

itemlist = listitems(heights)
# Python 2 and 3: option 3
from future.utils import iteritems
# or
from six import iteritems

itemlist = list(iteritems(heights))

自定义类的行为

自定义迭代器

# Python 2 only
class Upper(object):
    def __init__(self, iterable):
        self._iter = iter(iterable)
    def next(self):          # Py2-style
        return self._iter.next().upper()
    def __iter__(self):
        return self

itr = Upper('hello')
assert itr.next() == 'H'     # Py2-style
assert list(itr) == list('ELLO')
# Python 2 and 3: option 1
from future.builtins import object

class Upper(object):
    def __init__(self, iterable):
        self._iter = iter(iterable)
    def __next__(self):      # Py3-style iterator interface
        return next(self._iter).upper()  # builtin next() function calls
    def __iter__(self):
        return self

itr = Upper('hello')
assert next(itr) == 'H'      # compatible style
assert list(itr) == list('ELLO')
# Python 2 and 3: option 2
from future.utils import implements_iterator

@implements_iterator
class Upper(object):
    def __init__(self, iterable):
        self._iter = iter(iterable)
    def __next__(self):                  # Py3-style iterator interface
        return next(self._iter).upper()  # builtin next() function calls
    def __iter__(self):
        return self

itr = Upper('hello')
assert next(itr) == 'H'
assert list(itr) == list('ELLO')

自定义 __str__ 方法

# Python 2 only:
class MyClass(object):
    def __unicode__(self):
        return 'Unicode string: \u5b54\u5b50'
    def __str__(self):
        return unicode(self).encode('utf-8')

a = MyClass()
print(a)    # prints encoded string
# Python 2 and 3:
from future.utils import python_2_unicode_compatible

@python_2_unicode_compatible
class MyClass(object):
    def __str__(self):
        return u'Unicode string: \u5b54\u5b50'

a = MyClass()
print(a)    # prints string encoded as utf-8 on Py2
Unicode string: 孔子

自定义 __nonzero__ 对比 __bool__ 方法

# Python 2 only:
class AllOrNothing(object):
    def __init__(self, l):
        self.l = l
    def __nonzero__(self):
        return all(self.l)

container = AllOrNothing([0, 100, 200])
assert not bool(container)
# Python 2 and 3:
from future.builtins import object

class AllOrNothing(object):
    def __init__(self, l):
        self.l = l
    def __bool__(self):
        return all(self.l)

container = AllOrNothing([0, 100, 200])
assert not bool(container)

列表对迭代器

xrange

# Python 2 only:
for i in xrange(10**8):
    ...
# Python 2 and 3: forward-compatible
from future.builtins import range
for i in range(10**8):
    ...
# Python 2 and 3: backward-compatible
from past.builtins import xrange
for i in xrange(10**8):
    ...

range

# Python 2 only
mylist = range(5)
assert mylist == [0, 1, 2, 3, 4]
# Python 2 and 3: forward-compatible: option 1
mylist = list(range(5))            # copies memory on Py2
assert mylist == [0, 1, 2, 3, 4]
# Python 2 and 3: forward-compatible: option 2
from future.builtins import range

mylist = list(range(5))
assert mylist == [0, 1, 2, 3, 4]
# Python 2 and 3: option 3
from future.utils import lrange

mylist = lrange(5)
assert mylist == [0, 1, 2, 3, 4]
# Python 2 and 3: backward compatible
from past.builtins import range

mylist = range(5)
assert mylist == [0, 1, 2, 3, 4]

map

# Python 2 only:
mynewlist = map(f, myoldlist)
assert mynewlist == [f(x) for x in myoldlist]
# Python 2 and 3: option 1
# Idiomatic Py3, but inefficient on Py2
mynewlist = list(map(f, myoldlist))
assert mynewlist == [f(x) for x in myoldlist]
# Python 2 and 3: option 2
from future.builtins import map

mynewlist = list(map(f, myoldlist))
assert mynewlist == [f(x) for x in myoldlist]
# Python 2 and 3: option 3
try:
    import itertools.imap as map
except ImportError:
    pass

mynewlist = list(map(f, myoldlist))    # inefficient on Py2
assert mynewlist == [f(x) for x in myoldlist]
# Python 2 and 3: option 4
from future.utils import lmap

mynewlist = lmap(f, myoldlist)
assert mynewlist == [f(x) for x in myoldlist]
# Python 2 and 3: option 5
from past.builtins import map

mynewlist = map(f, myoldlist)
assert mynewlist == [f(x) for x in myoldlist]

imap

# Python 2 only:
from itertools import imap

myiter = imap(func, myoldlist)
assert isinstance(myiter, iter)
# Python 3 only:
myiter = map(func, myoldlist)
assert isinstance(myiter, iter)
# Python 2 and 3: option 1
from future.builtins import map

myiter = map(func, myoldlist)
assert isinstance(myiter, iter)
# Python 2 and 3: option 2
try:
    import itertools.imap as map
except ImportError:
    pass

myiter = map(func, myoldlist)
assert isinstance(myiter, iter)

zip, izip

As above with zip and itertools.izip.

filter, ifilter

As above with filter and itertools.ifilter too

其他内建函数

File IO with open()

# Python 2 only
f = open('myfile.txt')
data = f.read()              # as a byte string
text = data.decode('utf-8')

# Python 2 and 3: alternative 1
from io import open
f = open('myfile.txt', 'rb')
data = f.read()              # as bytes
text = data.decode('utf-8')  # unicode, not bytes

# Python 2 and 3: alternative 2
from io import open
f = open('myfile.txt', encoding='utf-8')
text = f.read()    # unicode, not bytes

reduce()

# Python 2 only:
assert reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) == 1+2+3+4+5
# Python 2 and 3:
from functools import reduce

assert reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) == 1+2+3+4+5

raw_input()

# Python 2 only:
name = raw_input('What is your name? ')
assert isinstance(name, str)    # native str
# Python 2 and 3:
from future.builtins import input

name = input('What is your name? ')
assert isinstance(name, str)    # native str on Py2 and Py3

input()

# Python 2 only:
input("Type something safe please: ")
# Python 2 and 3
from future.builtins import input
eval(input("Type something safe please: "))

警告:使用上面任何一个都是不安全的

file()

# Python 2 only:
f = file(pathname)
# Python 2 and 3:
f = open(pathname)

# But preferably, use this:
from io import open
f = open(pathname, 'rb')   # if f.read() should return bytes
# or
f = open(pathname, 'rt')   # if f.read() should return unicode text

execfile()

# Python 2 only:
execfile('myfile.py')
# Python 2 and 3: alternative 1
from past.builtins import execfile

execfile('myfile.py')
# Python 2 and 3: alternative 2
exec(compile(open('myfile.py').read()))

# This can sometimes cause this:
#     SyntaxError: function ... uses import * and bare exec ...
# See https://github.com/PythonCharmers/python-future/issues/37

unichr()

# Python 2 only:
assert unichr(8364) == '€'
# Python 3 only:
assert chr(8364) == '€'
# Python 2 and 3:
from future.builtins import chr
assert chr(8364) == '€'

intern()

# Python 2 only:
intern('mystring')
# Python 3 only:
from sys import intern
intern('mystring')
# Python 2 and 3: alternative 1
from past.builtins import intern
intern('mystring')
# Python 2 and 3: alternative 2
try:
    from sys import intern
except ImportError:
    pass
intern('mystring')

apply()

args = ('a', 'b')
kwargs = {'kwarg1': True}
# Python 2 only:
apply(f, args, kwargs)
# Python 2 and 3: alternative 1
f(*args, **kwargs)
# Python 2 and 3: alternative 2
from past.builtins import apply
apply(f, args, kwargs)

chr()

# Python 2 only:
assert chr(64) == b'@'
assert chr(200) == b'\xc8'
# Python 3 only: option 1
assert chr(64).encode('latin-1') == b'@'
assert chr(0xc8).encode('latin-1') == b'\xc8'
# Python 2 and 3: option 1
from future.builtins import chr

assert chr(64).encode('latin-1') == b'@'
assert chr(0xc8).encode('latin-1') == b'\xc8'
# Python 3 only: option 2
assert bytes([64]) == b'@'
assert bytes([0xc8]) == b'\xc8'
# Python 2 and 3: option 2
from future.builtins import bytes

assert bytes([64]) == b'@'
assert bytes([0xc8]) == b'\xc8'

cmp()

# Python 2 only:
assert cmp('a', 'b') < 0 and cmp('b', 'a') > 0 and cmp('c', 'c') == 0
# Python 2 and 3: alternative 1
from past.builtins import cmp
assert cmp('a', 'b') < 0 and cmp('b', 'a') > 0 and cmp('c', 'c') == 0
# Python 2 and 3: alternative 2
cmp = lambda(x, y): (x > y) - (x < y)
assert cmp('a', 'b') < 0 and cmp('b', 'a') > 0 and cmp('c', 'c') == 0

reload()

# Python 2 only:
reload(mymodule)
# Python 2 and 3
from imp import reload
reload(mymodule)

标准库

StringIO 模块

# Python 2 only
from StringIO import StringIO
from cStringIO import StringIO
# Python 2 and 3
from io import BytesIO
# and refactor StringIO() calls to BytesIO() if passing byte-strings

http 模块

# Python 2 only:
import httplib
import Cookie
import cookielib
import BaseHTTPServer
import SimpleHTTPServer
import CGIHttpServer

# Python 2 and 3:
from future.standard_library import hooks
with hooks():
    import http.client
    import http.cookies
    import http.cookiejar
    import http.server

urllib 模块

这个使用 urllib 的示例,相同的模式也适用于其他的已经移除的模块(一个完整的列表 http://python-future.org/standard_library_imports.html#list-of-standard-library-modules )

# Python 2 only:
from urlparse import urlparse
from urllib import urlencode
# Python 3 only:
from urllib.parse import urlparse, urlencode
# Python 2 and 3: alternative 1
from future.standard_library import hooks

with hooks():
    from urllib.parse import urlparse, urlencode
# Python 2 and 3: alternative 2
from future.moves.urllib.parse import urlparse, urlencode
# or
from six.moves.urllib.parse import urlparse, urlencode
# Python 2 and 3: alternative 3
try:
    from urllib.parse import urlparse, urlencode
except ImportError:
    from urlparse import urlparse
    from urllib import urlencode

© 著作权归作者所有

共有 人打赏支持
舒运
粉丝 7
博文 213
码字总数 510016
作品 0
深圳
解决python2与python3共存问题

python现在主要使用的有2个版本:2.x和3.x,而这2个版本的语法却有很多的不同,python3.x并不是向下兼容2.x的。虽然说3.x是未来python的主流,但是很多工具和个人还是倾向于python2.x,所以有...

lyj_viviani ⋅ 2017/03/06 ⋅ 0

初学者学习python2还是python3?

如果你是一个初学者,或者你以前接触过其他的编程语言,你可能不知道,在开始学习python的时候都会遇到一个比较让人很头疼的问题:版本问题!!是学习python2 还是学习 python3 ?这是非常让...

yunyingoldboy ⋅ 2017/11/09 ⋅ 0

《Python从小白到大牛》第3章 第一个Python程序

本章以HelloWorld作为切入点,介绍如何编写和运行Python程序代码。 运行Python程序主要有两种方式: 1.交互式方式运行 2.文件方式运行 本章介绍这两种运行方式实现HelloWorld程序。 使用P...

tony关东升 ⋅ 06/20 ⋅ 0

RHEL 8或将默认使用python3

Red Hat 宣布,它的企业级发行版 RHEL 下个大版本将用 Python 3 替代 Python 2。RHEL 刚刚发布了一个小版本 7.5,这意味着 8.0 版将正式移除 Python 2。Python 2.x 系列的最后版本 Python 2...

问题终结者 ⋅ 04/22 ⋅ 0

我们可以在同一个虚拟机中运行 Python 2 和 3 代码而不需要更改代码吗?

从理论上来说,可以。Zed Shaw 说过一句著名的话,如果不行,那么 Python 3 一定不是图灵完备的。但在实践中,这是不现实的,我将通过给你们举几个例子来说明原因。 对于字典(dict)来说,这...

作者: Łukasz Langa ⋅ 05/08 ⋅ 0

Python是如何怼翻其他编程语言而窜上宝座的

来PK啊! 谁怕谁啊! 在过去的两年间,Python一路高歌猛进,成功窜上“最火编程语言”的宝座。 更可怕的是,这把火不仅仅是在程序员的圈子里越烧越旺,甚至还烧到了程序员的圈子外,从小学生...

超级数学建模 ⋅ 04/18 ⋅ 0

荐书丨确认过眼神,这份Python书单一定是你的菜

点击上方“程序人生”,选择“置顶公众号” 第一时间关注程序猿(媛)身边的故事 Python 是军刀型的开源工具,被广泛应用于Web 开发、爬虫、数据清洗、自然语言处理、机器学习和人工智能等方...

csdnsevenn ⋅ 05/05 ⋅ 0

Python3的基本知识点(一)

Python的基础知识 1.Python的第一个程序 对于Python程序的编写有很多种方法,一般常见的编写程序有3种方式 1、利用超级终端编写: 打开超级终端:如图1所示, 2、利用sublime进行编写Python的...

长风留言 ⋅ 05/28 ⋅ 0

Python 3 的环境下如何正确地使用 Fabric

注:标题中「Fabric」指的是 Fabric( http://www.fabfile.org ),一个 Python 社区常用的远程/本地自动化执行工具。 讲 Fabric 之前,先讲讲我的 Python 开发环境。 很久以前,那会还在用 ...

I'm TualatriX ⋅ 05/21 ⋅ 0

Python(1)——python安装和第一个程序

/============================ 以下所有内容,均来自 廖雪峰 的官方网站, python 教程。 链接地址:http://www.liaoxuefeng.com ============================/ python 简介 1、python 是一...

docallen ⋅ 2017/04/25 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

volatile和synchronized的区别

volatile和synchronized的区别 在讲这个之前需要先了解下JMM(Java memory Model :java内存模型):并发过程中如何处理可见性、原子性、有序性的问题--建立JMM模型 详情请看:https://baike.b...

MarinJ_Shao ⋅ 41分钟前 ⋅ 0

深入分析Kubernetes Critical Pod(一)

Author: xidianwangtao@gmail.com 摘要:大家在部署Kubernetes集群AddOn组件的时候,经常会看到Annotation scheduler.alpha.kubernetes.io/critical-pod"="",以表示这是一个关键服务,那你知...

WaltonWang ⋅ 49分钟前 ⋅ 0

原子性 - synchronized关键词

原子性概念 原子性提供了程序的互斥操作,同一时刻只能有一个线程能对某块代码进行操作。 原子性的实现方式 在jdk中,原子性的实现方式主要分为: synchronized:关键词,它依赖于JVM,保证了同...

dotleo ⋅ 55分钟前 ⋅ 0

【2018.06.22学习笔记】【linux高级知识 14.4-15.3】

14.4 exportfs命令 14.5 NFS客户端问题 15.1 FTP介绍 15.2/15.3 使用vsftpd搭建ftp

lgsxp ⋅ 今天 ⋅ 0

JeeSite 4.0 功能权限管理基础(Shiro)

Shiro是Apache的一个开源框架,是一个权限管理的框架,实现用户认证、用户授权等。 只要有用户参与一般都要有权限管理,权限管理实现对用户访问系统的控制,按照安全规则或者安全策略控制用户...

ThinkGem ⋅ 昨天 ⋅ 0

python f-string 字符串格式化

主要内容 从Python 3.6开始,f-string是格式化字符串的一种很好的新方法。与其他格式化方式相比,它们不仅更易读,更简洁,不易出错,而且速度更快! 在本文的最后,您将了解如何以及为什么今...

阿豪boy ⋅ 昨天 ⋅ 0

Python实现自动登录站点

如果我们想要实现自动登录,那么我们就需要能够驱动浏览器(比如谷歌浏览器)来实现操作,ChromeDriver 刚好能够帮助我们这一点(非谷歌浏览器的驱动有所不同)。 一、确认软件版本 首先我们...

blackfoxya ⋅ 昨天 ⋅ 0

线性回归原理和实现基本认识

一:介绍 定义:线性回归在假设特证满足线性关系,根据给定的训练数据训练一个模型,并用此模型进行预测。为了了解这个定义,我们先举个简单的例子;我们假设一个线性方程 Y=2x+1, x变量为商...

wangxuwei ⋅ 昨天 ⋅ 0

容器之查看minikue的environment——minikube的环境信息

执行如下命令 mjduan@mjduandeMacBook-Pro:~/Docker % minikube docker-envexport DOCKER_TLS_VERIFY="1"export DOCKER_HOST="tcp://192.168.99.100:2376"export DOCKER_CERT_PATH="/U......

汉斯-冯-拉特 ⋅ 昨天 ⋅ 0

mysql远程连接不上

设置了root所有hosts远程登录,可是远程登录还是失败,原因可能如下: 登录本地数据库 mysql -uroot -p123456 查询用户表 mysql> select user,host,password from mysql.user; 删除密码为空的...

冰公子 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部