标签归档:egg

在config.py中提供全局配置变量的最Pythonic方法?[关闭]

问题:在config.py中提供全局配置变量的最Pythonic方法?[关闭]

在我对过度复杂的简单事物的无尽追求中,我正在研究最“ Pythonic”的方法来在Python egg包中的典型“ config.py ”中提供全局配置变量。

传统方式(啊,好吧,# define!)如下:

MYSQL_PORT = 3306
MYSQL_DATABASE = 'mydb'
MYSQL_DATABASE_TABLES = ['tb_users', 'tb_groups']

因此,以下列方式之一导入全局变量:

from config import *
dbname = MYSQL_DATABASE
for table in MYSQL_DATABASE_TABLES:
    print table

要么:

import config
dbname = config.MYSQL_DATABASE
assert(isinstance(config.MYSQL_PORT, int))

这是有道理的,但有时可能会有些混乱,尤其是在您要记住某些变量的名称时。此外,提供一个以变量为属性“配置”对象可能更灵活。因此,从bpython config.py文件开始,我想到了:

class Struct(object):

    def __init__(self, *args):
        self.__header__ = str(args[0]) if args else None

    def __repr__(self):
        if self.__header__ is None:
             return super(Struct, self).__repr__()
        return self.__header__

    def next(self):
        """ Fake iteration functionality.
        """
        raise StopIteration

    def __iter__(self):
        """ Fake iteration functionality.
        We skip magic attribues and Structs, and return the rest.
        """
        ks = self.__dict__.keys()
        for k in ks:
            if not k.startswith('__') and not isinstance(k, Struct):
                yield getattr(self, k)

    def __len__(self):
        """ Don't count magic attributes or Structs.
        """
        ks = self.__dict__.keys()
        return len([k for k in ks if not k.startswith('__')\
                    and not isinstance(k, Struct)])

和一个“ config.py”,该类导入该类,内容如下:

from _config import Struct as Section

mysql = Section("MySQL specific configuration")
mysql.user = 'root'
mysql.pass = 'secret'
mysql.host = 'localhost'
mysql.port = 3306
mysql.database = 'mydb'

mysql.tables = Section("Tables for 'mydb'")
mysql.tables.users = 'tb_users'
mysql.tables.groups =  'tb_groups'

并以这种方式使用:

from sqlalchemy import MetaData, Table
import config as CONFIG

assert(isinstance(CONFIG.mysql.port, int))

mdata = MetaData(
    "mysql://%s:%s@%s:%d/%s" % (
         CONFIG.mysql.user,
         CONFIG.mysql.pass,
         CONFIG.mysql.host,
         CONFIG.mysql.port,
         CONFIG.mysql.database,
     )
)

tables = []
for name in CONFIG.mysql.tables:
    tables.append(Table(name, mdata, autoload=True))

这似乎是在包内存储和获取全局变量的一种更具可读性,表现力和灵活性的方式。

有史以来最大的想法?应对这些情况的最佳实践是什么?什么是您的存储和获取全局名称和变量您的包内的方法吗?

In my endless quest in over-complicating simple stuff, I am researching the most ‘Pythonic’ way to provide global configuration variables inside the typical ‘config.py‘ found in Python egg packages.

The traditional way (aah, good ol’ #define!) is as follows:

MYSQL_PORT = 3306
MYSQL_DATABASE = 'mydb'
MYSQL_DATABASE_TABLES = ['tb_users', 'tb_groups']

Therefore global variables are imported in one of the following ways:

from config import *
dbname = MYSQL_DATABASE
for table in MYSQL_DATABASE_TABLES:
    print table

or:

import config
dbname = config.MYSQL_DATABASE
assert(isinstance(config.MYSQL_PORT, int))

It makes sense, but sometimes can be a little messy, especially when you’re trying to remember the names of certain variables. Besides, providing a ‘configuration’ object, with variables as attributes, might be more flexible. So, taking a lead from bpython config.py file, I came up with:

class Struct(object):

    def __init__(self, *args):
        self.__header__ = str(args[0]) if args else None

    def __repr__(self):
        if self.__header__ is None:
             return super(Struct, self).__repr__()
        return self.__header__

    def next(self):
        """ Fake iteration functionality.
        """
        raise StopIteration

    def __iter__(self):
        """ Fake iteration functionality.
        We skip magic attribues and Structs, and return the rest.
        """
        ks = self.__dict__.keys()
        for k in ks:
            if not k.startswith('__') and not isinstance(k, Struct):
                yield getattr(self, k)

    def __len__(self):
        """ Don't count magic attributes or Structs.
        """
        ks = self.__dict__.keys()
        return len([k for k in ks if not k.startswith('__')\
                    and not isinstance(k, Struct)])

and a ‘config.py’ that imports the class and reads as follows:

from _config import Struct as Section

mysql = Section("MySQL specific configuration")
mysql.user = 'root'
mysql.pass = 'secret'
mysql.host = 'localhost'
mysql.port = 3306
mysql.database = 'mydb'

mysql.tables = Section("Tables for 'mydb'")
mysql.tables.users = 'tb_users'
mysql.tables.groups =  'tb_groups'

and is used in this way:

from sqlalchemy import MetaData, Table
import config as CONFIG

assert(isinstance(CONFIG.mysql.port, int))

mdata = MetaData(
    "mysql://%s:%s@%s:%d/%s" % (
         CONFIG.mysql.user,
         CONFIG.mysql.pass,
         CONFIG.mysql.host,
         CONFIG.mysql.port,
         CONFIG.mysql.database,
     )
)

tables = []
for name in CONFIG.mysql.tables:
    tables.append(Table(name, mdata, autoload=True))

Which seems a more readable, expressive and flexible way of storing and fetching global variables inside a package.

Lamest idea ever? What is the best practice for coping with these situations? What is your way of storing and fetching global names and variables inside your package?


回答 0

我做了一次。最终,我发现简化的basicconfig.py可以满足我的需求。如果需要,您可以将命名空间与其他对象一起传递以供其引用。您还可以从代码中传递其他默认值。它还将属性和映射样式语法映射到同一配置对象。

I did that once. Ultimately I found my simplified basicconfig.py adequate for my needs. You can pass in a namespace with other objects for it to reference if you need to. You can also pass in additional defaults from your code. It also maps attribute and mapping style syntax to the same configuration object.


回答 1

只使用这样的内置类型怎么样:

config = {
    "mysql": {
        "user": "root",
        "pass": "secret",
        "tables": {
            "users": "tb_users"
        }
        # etc
    }
}

您可以按以下方式访问这些值:

config["mysql"]["tables"]["users"]

如果您愿意牺牲潜力在配置树中计算表达式,则可以使用YAML并得到一个更具可读性的配置文件,如下所示:

mysql:
  - user: root
  - pass: secret
  - tables:
    - users: tb_users

并使用PyYAML之类的库方便地解析和访问配置文件

How about just using the built-in types like this:

config = {
    "mysql": {
        "user": "root",
        "pass": "secret",
        "tables": {
            "users": "tb_users"
        }
        # etc
    }
}

You’d access the values as follows:

config["mysql"]["tables"]["users"]

If you are willing to sacrifice the potential to compute expressions inside your config tree, you could use YAML and end up with a more readable config file like this:

mysql:
  - user: root
  - pass: secret
  - tables:
    - users: tb_users

and use a library like PyYAML to conventiently parse and access the config file


回答 2

我喜欢用于小型应用程序的解决方案:

class App:
  __conf = {
    "username": "",
    "password": "",
    "MYSQL_PORT": 3306,
    "MYSQL_DATABASE": 'mydb',
    "MYSQL_DATABASE_TABLES": ['tb_users', 'tb_groups']
  }
  __setters = ["username", "password"]

  @staticmethod
  def config(name):
    return App.__conf[name]

  @staticmethod
  def set(name, value):
    if name in App.__setters:
      App.__conf[name] = value
    else:
      raise NameError("Name not accepted in set() method")

然后用法是:

if __name__ == "__main__":
   # from config import App
   App.config("MYSQL_PORT")     # return 3306
   App.set("username", "hi")    # set new username value
   App.config("username")       # return "hi"
   App.set("MYSQL_PORT", "abc") # this raises NameError

..您应该喜欢它,因为:

  • 使用类变量(无需传递对象/无需单例),
  • 使用封装的内置类型,看起来像是在上的方法调用App
  • 可以控制个人配置的不变性可变全局变量是最差的全局变量
  • 在您的源代码中提高常规名称的访问/可读性
  • 是一个简单的类,但是强制进行结构化访问,一种替代方法是使用@property,但是每个项目需要更多的变量处理代码,并且是基于对象的。
  • 只需进行最小的更改即可添加新的配置项并设置其可变性。

-编辑-:对于大型应用程序,将值存储在YAML(即属性)文件中并将其作为不可变数据读取是一种更好的方法(即blubb / ohaal的答案)。对于小型应用程序,上面的解决方案更简单。

I like this solution for small applications:

class App:
  __conf = {
    "username": "",
    "password": "",
    "MYSQL_PORT": 3306,
    "MYSQL_DATABASE": 'mydb',
    "MYSQL_DATABASE_TABLES": ['tb_users', 'tb_groups']
  }
  __setters = ["username", "password"]

  @staticmethod
  def config(name):
    return App.__conf[name]

  @staticmethod
  def set(name, value):
    if name in App.__setters:
      App.__conf[name] = value
    else:
      raise NameError("Name not accepted in set() method")

And then usage is:

if __name__ == "__main__":
   # from config import App
   App.config("MYSQL_PORT")     # return 3306
   App.set("username", "hi")    # set new username value
   App.config("username")       # return "hi"
   App.set("MYSQL_PORT", "abc") # this raises NameError

.. you should like it because:

  • uses class variables (no object to pass around/ no singleton required),
  • uses encapsulated built-in types and looks like (is) a method call on App,
  • has control over individual config immutability, mutable globals are the worst kind of globals.
  • promotes conventional and well named access / readability in your source code
  • is a simple class but enforces structured access, an alternative is to use @property, but that requires more variable handling code per item and is object-based.
  • requires minimal changes to add new config items and set its mutability.

–Edit–: For large applications, storing values in a YAML (i.e. properties) file and reading that in as immutable data is a better approach (i.e. blubb/ohaal’s answer). For small applications, this solution above is simpler.


回答 3

使用类怎么样?

# config.py
class MYSQL:
    PORT = 3306
    DATABASE = 'mydb'
    DATABASE_TABLES = ['tb_users', 'tb_groups']

# main.py
from config import MYSQL

print(MYSQL.PORT) # 3306

How about using classes?

# config.py
class MYSQL:
    PORT = 3306
    DATABASE = 'mydb'
    DATABASE_TABLES = ['tb_users', 'tb_groups']

# main.py
from config import MYSQL

print(MYSQL.PORT) # 3306

回答 4

类似于blubb的答案。我建议使用lambda函数构建它们以减少代码。像这样:

User = lambda passwd, hair, name: {'password':passwd, 'hair':hair, 'name':name}

#Col      Username       Password      Hair Color  Real Name
config = {'st3v3' : User('password',   'blonde',   'Steve Booker'),
          'blubb' : User('12345678',   'black',    'Bubb Ohaal'),
          'suprM' : User('kryptonite', 'black',    'Clark Kent'),
          #...
         }
#...

config['st3v3']['password']  #> password
config['blubb']['hair']      #> black

不过,这确实闻起来像您可能想上一堂课。

或者,如MarkM所述,您可以使用 namedtuple

from collections import namedtuple
#...

User = namedtuple('User', ['password', 'hair', 'name']}

#Col      Username       Password      Hair Color  Real Name
config = {'st3v3' : User('password',   'blonde',   'Steve Booker'),
          'blubb' : User('12345678',   'black',    'Bubb Ohaal'),
          'suprM' : User('kryptonite', 'black',    'Clark Kent'),
          #...
         }
#...

config['st3v3'].password   #> passwd
config['blubb'].hair       #> black

Similar to blubb’s answer. I suggest building them with lambda functions to reduce code. Like this:

User = lambda passwd, hair, name: {'password':passwd, 'hair':hair, 'name':name}

#Col      Username       Password      Hair Color  Real Name
config = {'st3v3' : User('password',   'blonde',   'Steve Booker'),
          'blubb' : User('12345678',   'black',    'Bubb Ohaal'),
          'suprM' : User('kryptonite', 'black',    'Clark Kent'),
          #...
         }
#...

config['st3v3']['password']  #> password
config['blubb']['hair']      #> black

This does smell like you may want to make a class, though.

Or, as MarkM noted, you could use namedtuple

from collections import namedtuple
#...

User = namedtuple('User', ['password', 'hair', 'name']}

#Col      Username       Password      Hair Color  Real Name
config = {'st3v3' : User('password',   'blonde',   'Steve Booker'),
          'blubb' : User('12345678',   'black',    'Bubb Ohaal'),
          'suprM' : User('kryptonite', 'black',    'Clark Kent'),
          #...
         }
#...

config['st3v3'].password   #> passwd
config['blubb'].hair       #> black

回答 5

我使用的赫斯基想法略有不同。创建一个名为“ globals”(或您喜欢的文件)的文件,然后在其中定义多个类,如下所示:

#globals.py

class dbinfo :      # for database globals
    username = 'abcd'
    password = 'xyz'

class runtime :
    debug = False
    output = 'stdio'

然后,如果您有两个代码文件c1.py和c2.py,则两者都可以位于顶部

import globals as gl

现在,所有代码都可以访问和设置值,如下所示:

gl.runtime.debug = False
print(gl.dbinfo.username)

人们会忘记存在类,即使没有实例化属于该类成员的对象也是如此。并且类中没有“自我”的变量。在类的所有实例之间共享,即使没有实例也是如此。一旦任何代码更改了“调试”,所有其他代码都将看到更改。

通过将其导入为gl,您可以拥有多个这样的文件和变量,使您可以跨代码文件,函数等访问和设置值,但不会发生命名空间冲突的危险。

这缺少其他方法的一些聪明的错误检查,但是简单易行。

A small variation on Husky’s idea that I use. Make a file called ‘globals’ (or whatever you like) and then define multiple classes in it, as such:

#globals.py

class dbinfo :      # for database globals
    username = 'abcd'
    password = 'xyz'

class runtime :
    debug = False
    output = 'stdio'

Then, if you have two code files c1.py and c2.py, both can have at the top

import globals as gl

Now all code can access and set values, as such:

gl.runtime.debug = False
print(gl.dbinfo.username)

People forget classes exist, even if no object is ever instantiated that is a member of that class. And variables in a class that aren’t preceded by ‘self.’ are shared across all instances of the class, even if there are none. Once ‘debug’ is changed by any code, all other code sees the change.

By importing it as gl, you can have multiple such files and variables that lets you access and set values across code files, functions, etc., but with no danger of namespace collision.

This lacks some of the clever error checking of other approaches, but is simple and easy to follow.


回答 6

坦白地说,我们可能应该考虑使用Python Software Foundation维护的库:

https://docs.python.org/3/library/configparser.html

配置示例:(ini格式,但可用JSON)

[DEFAULT]
ServerAliveInterval = 45
Compression = yes
CompressionLevel = 9
ForwardX11 = yes

[bitbucket.org]
User = hg

[topsecret.server.com]
Port = 50022
ForwardX11 = no

代码示例:

>>> import configparser
>>> config = configparser.ConfigParser()
>>> config.read('example.ini')
>>> config['DEFAULT']['Compression']
'yes'
>>> config['DEFAULT'].getboolean('MyCompression', fallback=True) # get_or_else

使其可全局访问:

import configpaser
class App:
 __conf = None

 @staticmethod
 def config():
  if App.__conf is None:  # Read only once, lazy.
   App.__conf = configparser.ConfigParser()
   App.__conf.read('example.ini')
  return App.__conf

if __name__ == '__main__':
 App.config()['DEFAULT']['MYSQL_PORT']
 # or, better:
 App.config().get(section='DEFAULT', option='MYSQL_PORT', fallback=3306)
 ....

缺点:

  • 不受控制的全局可变状态。

Let’s be honest, we should probably consider using a Python Software Foundation maintained library:

https://docs.python.org/3/library/configparser.html

Config example: (ini format, but JSON available)

[DEFAULT]
ServerAliveInterval = 45
Compression = yes
CompressionLevel = 9
ForwardX11 = yes

[bitbucket.org]
User = hg

[topsecret.server.com]
Port = 50022
ForwardX11 = no

Code example:

>>> import configparser
>>> config = configparser.ConfigParser()
>>> config.read('example.ini')
>>> config['DEFAULT']['Compression']
'yes'
>>> config['DEFAULT'].getboolean('MyCompression', fallback=True) # get_or_else

Making it globally-accessible:

import configpaser
class App:
 __conf = None

 @staticmethod
 def config():
  if App.__conf is None:  # Read only once, lazy.
   App.__conf = configparser.ConfigParser()
   App.__conf.read('example.ini')
  return App.__conf

if __name__ == '__main__':
 App.config()['DEFAULT']['MYSQL_PORT']
 # or, better:
 App.config().get(section='DEFAULT', option='MYSQL_PORT', fallback=3306)
 ....

Downsides:

  • Uncontrolled global mutable state.

回答 7

请检出通过traitlet实现的IPython配置系统,以实现您正在手动执行的类型强制。

在此处进行剪切和粘贴,以符合SO准则,而不仅仅是随着链接的内容随时间变化而删除链接。

特征文档

这是我们希望我们的配置系统具有的主要要求:

支持分层配置信息。

与命令行选项解析器完全集成。通常,您想读取配置文件,然后使用命令行选项覆盖某些值。我们的配置系统使该过程自动化,并允许将每个命令行选项链接到将被覆盖的配置层次结构中的特定属性。

配置文件本身就是有效的Python代码。这完成了很多事情。首先,可以将逻辑放入配置文件中,以根据操作系统,网络设置,Python版本等设置属性。其次,Python具有用于访问分层数据结构的超简单语法,即常规属性访问(Foo。 Bar.Bam.name)。第三,使用Python可使用户轻松地将配置属性从一个配置文件导入到另一个。第四,即使Python是动态类型的,它也确实具有可以在运行时检查的类型。因此,配置文件中的1是整数’1’,而’1’是字符串。

一种在运行时将配置信息获取到需要它的类的全自动方法。编写遍历配置层次结构以提取特定属性的代码很痛苦。当您具有包含数百个属性的复杂配置信息时,这会让您想哭。

类型检查和验证不需要在运行时之前静态地指定整个配置层次结构。Python是一种非常动态的语言,您并不总是知道程序启动时需要配置的所有内容。

为此,他们基本上定义了3个对象类以及它们之间的关系:

1)配置-基本上是ChainMap /基本dict,具有一些用于合并的增强功能。

2)可配置-基类可将您要配置的所有内容都子类化。

3)应用程序-实例化以执行特定应用程序功能的对象,或用于单一目的软件的主应用程序。

用他们的话说:

应用:应用

应用程序是执行特定工作的过程。最明显的应用是ipython命令行程序。每个应用程序都读取一个或多个配置文件和一组命令行选项,然后为该应用程序生成一个主配置对象。然后,此配置对象将传递到应用程序创建的可配置对象。这些可配置对象实现了应用程序的实际逻辑,并且知道如何在给定配置对象的情况下进行自我配置。

应用程序始终具有配置为Logger的日志属性。这允许对每个应用程序进行集中式日志记录配置。可配置:可配置

可配置的是常规Python类,它充当应用程序中所有主要类的基类。可配置基类是轻量级的,只能做一件事。

此Configurable是HasTraits的子类,它知道如何进行自我配置。具有元数据config = True的类级别特征变为可以从命令行和配置文件配置的值。

开发人员创建可配置的子类,以实现应用程序中的所有逻辑。这些子类中的每一个都有其自己的配置信息,该信息控制如何创建实例。

please check out the IPython configuration system, implemented via traitlets for the type enforcement you are doing manually.

Cut and pasted here to comply with SO guidelines for not just dropping links as the content of links changes over time.

traitlets documentation

Here are the main requirements we wanted our configuration system to have:

Support for hierarchical configuration information.

Full integration with command line option parsers. Often, you want to read a configuration file, but then override some of the values with command line options. Our configuration system automates this process and allows each command line option to be linked to a particular attribute in the configuration hierarchy that it will override.

Configuration files that are themselves valid Python code. This accomplishes many things. First, it becomes possible to put logic in your configuration files that sets attributes based on your operating system, network setup, Python version, etc. Second, Python has a super simple syntax for accessing hierarchical data structures, namely regular attribute access (Foo.Bar.Bam.name). Third, using Python makes it easy for users to import configuration attributes from one configuration file to another. Fourth, even though Python is dynamically typed, it does have types that can be checked at runtime. Thus, a 1 in a config file is the integer ‘1’, while a ‘1’ is a string.

A fully automated method for getting the configuration information to the classes that need it at runtime. Writing code that walks a configuration hierarchy to extract a particular attribute is painful. When you have complex configuration information with hundreds of attributes, this makes you want to cry.

Type checking and validation that doesn’t require the entire configuration hierarchy to be specified statically before runtime. Python is a very dynamic language and you don’t always know everything that needs to be configured when a program starts.

To acheive this they basically define 3 object classes and their relations to each other:

1) Configuration – basically a ChainMap / basic dict with some enhancements for merging.

2) Configurable – base class to subclass all things you’d wish to configure.

3) Application – object that is instantiated to perform a specific application function, or your main application for single purpose software.

In their words:

Application: Application

An application is a process that does a specific job. The most obvious application is the ipython command line program. Each application reads one or more configuration files and a single set of command line options and then produces a master configuration object for the application. This configuration object is then passed to the configurable objects that the application creates. These configurable objects implement the actual logic of the application and know how to configure themselves given the configuration object.

Applications always have a log attribute that is a configured Logger. This allows centralized logging configuration per-application. Configurable: Configurable

A configurable is a regular Python class that serves as a base class for all main classes in an application. The Configurable base class is lightweight and only does one things.

This Configurable is a subclass of HasTraits that knows how to configure itself. Class level traits with the metadata config=True become values that can be configured from the command line and configuration files.

Developers create Configurable subclasses that implement all of the logic in the application. Each of these subclasses has its own configuration information that controls how instances are created.


有与Ruby的“ rvm”等效的python吗?

问题:有与Ruby的“ rvm”等效的python吗?

问:在Python中,我们有功能上与Ruby版本管理器“ rvm”等效的功能吗?


RVM使您可以轻松地在不同版本的ruby解释器不同组的gem(模块)之间进行完全切换。有关解释器 gems的download-build-install-switch的一切,都可以通过调用rvm来解决。全部以您的普通用户帐户运行。)

Q: Do we have anything functionally equivalent in Python to the Ruby version manager ‘rvm’?


(RVM lets you easily switch completely between different versions of the ruby interpreter and different sets of gems (modules). Everything concerning download-build-install-switch of interpreter(-s) and gems gets taken care of by invoking rvm. It is all run under your regular user account.)


回答 0

是的,它与virtualenvwrapper一起是virtualenv

更新:您可以一次安装virtualenv burrito

更新:正确的答案现在可能是pyenv

对于科学计算,相应的工具是anaconda

Yes, it is virtualenv along with virtualenvwrapper.

update: you may install both at once with virtualenv burrito.

Update: the correct answer is now probably pyenv.

For scientific computing, the corresponding tool is anaconda.


回答 1

Pythonbrew不再在开发中。前维护者建议改用“ PyEnv”(见下文)”。

pythonbrew来了! http://github.com/utahta/pythonbrew

pyenv:https//github.com/yyuu/pyenv

Pythonbrew is no longer under development. The former maintainer suggests to use “PyEnv” instead (see below)”.

pythonbrew has come! http://github.com/utahta/pythonbrew

pyenv: https://github.com/yyuu/pyenv


回答 2

我创建了pyenv,它是Ruby的rbenv的一个分支,并针对Python进行了修改。像pythonz一样,pyenv还支持Stackless,PyPy和Jython。

I created pyenv which is a fork of Ruby’s rbenv and modified for Python. Like pythonz, pyenv also supports Stackless, PyPy, and Jython.


回答 3

跟进hytdsh的回答(近两年后)…

pythonz pythonbrew的一个分支,增加了对Stackless,PyPy和Jython的支持。

如果您喜欢rvm处理不同解释器的方式,那么可能值得看看pythonz。如果您严格使用CPython,则差异不那么明显。

Following up on hytdsh’s answer (nearly two years later)…

pythonz a fork of pythonbrew that adds support for Stackless, PyPy, and Jython.

If you like how rvm handles different interpreters, it may worth taking a look at pythonz. If you’re strictly working with CPython, the difference is less significant.


回答 4

或者,如果您使用的是Macports,则可以使用python_select。安装python_select方式:

$ sudo port install python_select

假设python 2.6和2.5通过Macports安装了bee,则可以像这样切换python:

$ sudo python_select python25
=> Selecting version "python25" for python
$ python --version
=> 2.5.5
$ sudo python_select python26
=> Selecting version "python26" for python
$ python --version
=> 2.6.6

Optionally, if you’re using Macports you can use python_select. Install python_select with:

$ sudo port install python_select

Assuming python 2.6 and 2.5 have bee installed via Macports you can switch pythons like so:

$ sudo python_select python25
=> Selecting version "python25" for python
$ python --version
=> 2.5.5
$ sudo python_select python26
=> Selecting version "python26" for python
$ python --version
=> 2.6.6

回答 5

pyenv 1.2.15可以为您构建和安装Python

也许这在早期版本中是不可能的,但是当我在1.2.15中进行测试时,我注意到该pyenv install选项有效:

pyenv install 3.8.0

因此,我认为调用pyenvRVM的替代品是合理的。

我在以下位置给出了其用法的完整详细示例:针对不同python版本的apt-get install

pyenv 1.2.15 can build and install Python for you

Maybe this was not possible in earlier version, but when I tested in 1.2.15 I noticed the pyenv install option which worked:

pyenv install 3.8.0

Therefore I feel that it is reasonable to call pyenv a replacement for RVM.

I have given a fully detailed example of its usage at: apt-get install for different python versions


什么是Python鸡蛋?

问题:什么是Python鸡蛋?

我是Python的新手,只是想了解它的软件包是如何工作的。大概“蛋”是某种包装机制,但是如何快速概述它们所扮演的角色,以及可能提供有关为什么它们有用以及如何创建它们的一些信息?

I’m new to Python and am just trying to understand how its packages work. Presumably “eggs” are some sort of packaging mechanism, but what would be a quick overview of what role they play and may be some information on why they’re useful and how to create them?


回答 0

注意:鸡蛋包装已被滚轮包装取代。

.jarJava文件的概念相同,它是.zip重命名了一些元数据文件的文件.egg,用于将代码作为分发包分发。

具体来说:Python Eggs的内部结构

“ Python鸡蛋”是一种逻辑结构,体现了特定版本的Python项目的发布,包括其代码,资源和元数据。可以使用多种格式对Python鸡蛋进行物理编码,还可以开发其他格式。但是,Python鸡蛋的关键原则是它们应该是可发现的和可导入的。也就是说,Python应用程序应该有可能轻松有效地找出系统中存在的卵,并确保所需卵的内容可导入。

.egg格式非常适合于分发以及代码的轻松卸载或升级,因为该项目本质上是独立的,包含在单个目录或文件中,没有与任何其他项目的代码或资源混合在一起。它还可以同时安装一个项目的多个版本,以便各个程序可以选择他们想要使用的版本。

Note: Egg packaging has been superseded by Wheel packaging.

Same concept as a .jar file in Java, it is a .zip file with some metadata files renamed .egg, for distributing code as bundles.

Specifically: The Internal Structure of Python Eggs

A “Python egg” is a logical structure embodying the release of a specific version of a Python project, comprising its code, resources, and metadata. There are multiple formats that can be used to physically encode a Python egg, and others can be developed. However, a key principle of Python eggs is that they should be discoverable and importable. That is, it should be possible for a Python application to easily and efficiently find out what eggs are present on a system, and to ensure that the desired eggs’ contents are importable.

The .egg format is well-suited to distribution and the easy uninstallation or upgrades of code, since the project is essentially self-contained within a single directory or file, unmingled with any other projects’ code or resources. It also makes it possible to have multiple versions of a project simultaneously installed, such that individual programs can select the versions they wish to use.


回答 1

.egg文件是Python软件包的分发格式。它只是源代码发行版或Windows的替代方案exe。但是请注意,对于pure Python.egg文件是完全跨平台的。

.egg文件本身实质上是一个.zip文件。如果将扩展名更改为“ zip”,则可以看到它在存档中将包含文件夹。

另外,如果您有.egg文件,则可以使用以下文件作为软件包安装easy_install

示例:要.egg为目录创建一个文件,例如mymath它本身可能具有多个python脚本,请执行以下步骤:

# setup.py
from setuptools import setup, find_packages
setup(
    name = "mymath",
    version = "0.1",
    packages = find_packages()
    )

然后,从终端执行:

 $ python setup.py bdist_egg

这将产生很多输出,但是完成后,您会看到拥有三个新文件夹:builddistmymath.egg-info。我们唯一关心的文件夹是dist文件夹,您可以在其中找到.egg文件,mymath-0.1-py3.5.egg带有默认的python(安装)版本号(此处为3.5)

资料来源:Python库博客

The .egg file is a distribution format for Python packages. It’s just an alternative to a source code distribution or Windows exe. But note that for pure Python, the .egg file is completely cross-platform.

The .egg file itself is essentially a .zip file. If you change the extension to “zip”, you can see that it will have folders inside the archive.

Also, if you have an .egg file, you can install it as a package using easy_install

Example: To create an .egg file for a directory say mymath which itself may have several python scripts, do the following step:

# setup.py
from setuptools import setup, find_packages
setup(
    name = "mymath",
    version = "0.1",
    packages = find_packages()
    )

Then, from the terminal do:

 $ python setup.py bdist_egg

This will generate lot of outputs, but when it’s completed you’ll see that you have three new folders: build, dist, and mymath.egg-info. The only folder that we care about is the dist folder where you’ll find your .egg file, mymath-0.1-py3.5.egg with your default python (installation) version number(mine here: 3.5)

Source: Python library blog


回答 2

Python蛋是将附加信息与Python项目捆绑在一起的一种方式,它允许在运行时检查和满足项目的依赖关系,并允许项目为其他项目提供插件。有几种包含鸡蛋的二进制格式,但是最常见的是’.egg’zipfile格式,因为它是分发项目的便捷方式。所有格式都支持,包括特定于软件包的数据,项目范围的元数据,C扩展名和Python代码。

安装和使用Python egg的最简单方法是使用“简易安装” Python软件包管理器,它将为您查找,下载,构建和安装egg。您要做的就是告诉它您要使用的Python项目的名称(以及版本)。

Python鸡蛋可以与Python 2.3及更高版本一起使用,并且可以使用setuptools软件包进行构建(有关源代码,请参见Python Subversion沙箱;有关当前安装说明,请参见EasyInstall页面)。

Python Eggs的主要好处是:

  • 它们启用了诸如“轻松安装” Python软件包管理器之类的工具

  • .egg文件是Python软件包的“零安装”格式;无需构建或安装步骤,只需将它们放在PYTHONPATH或sys.path上并使用它们即可(如果使用C扩展名或数据文件,则可能需要安装运行时)

  • 它们可以包括包元数据,例如它们依赖的其他鸡蛋

  • 它们允许将“命名空间包”(仅包含其他包的包)拆分为单独的分布(例如zope。,twisted。,peak。*)包可以作为单独的鸡蛋分发,这与通常必须始终放在同一包下的普通包不同父目录。这允许将现在庞大的整体软件包作为单独的组件分发。)

  • 它们允许应用程序或库指定库的所需版本,以便您可以在导入twisted.internet之前例如require(“ Twisted-Internet> = 2.0”)。

  • 对于将扩展或插件分发到可扩展的应用程序和框架,它们是一种很好的格式(例如Trac,它从0.9b1开始使用鸡蛋作为插件),因为Egg运行时提供了简单的API来查找鸡蛋并找到其广告入口点(类似Eclipse的“扩展点”概念)。

标准化格式还会带来其他好处,类似于Java的“ jar”格式的好处。

Python eggs are a way of bundling additional information with a Python project, that allows the project’s dependencies to be checked and satisfied at runtime, as well as allowing projects to provide plugins for other projects. There are several binary formats that embody eggs, but the most common is ‘.egg’ zipfile format, because it’s a convenient one for distributing projects. All of the formats support including package-specific data, project-wide metadata, C extensions, and Python code.

The easiest way to install and use Python eggs is to use the “Easy Install” Python package manager, which will find, download, build, and install eggs for you; all you do is tell it the name (and optionally, version) of the Python project(s) you want to use.

Python eggs can be used with Python 2.3 and up, and can be built using the setuptools package (see the Python Subversion sandbox for source code, or the EasyInstall page for current installation instructions).

The primary benefits of Python Eggs are:

  • They enable tools like the “Easy Install” Python package manager

  • .egg files are a “zero installation” format for a Python package; no build or install step is required, just put them on PYTHONPATH or sys.path and use them (may require the runtime installed if C extensions or data files are used)

  • They can include package metadata, such as the other eggs they depend on

  • They allow “namespace packages” (packages that just contain other packages) to be split into separate distributions (e.g. zope., twisted., peak.* packages can be distributed as separate eggs, unlike normal packages which must always be placed under the same parent directory. This allows what are now huge monolithic packages to be distributed as separate components.)

  • They allow applications or libraries to specify the needed version of a library, so that you can e.g. require(“Twisted-Internet>=2.0”) before doing an import twisted.internet.

  • They’re a great format for distributing extensions or plugins to extensible applications and frameworks (such as Trac, which uses eggs for plugins as of 0.9b1), because the egg runtime provides simple APIs to locate eggs and find their advertised entry points (similar to Eclipse’s “extension point” concept).

There are also other benefits that may come from having a standardized format, similar to the benefits of Java’s “jar” format.


回答 3

“ Egg”是与Python相关的项目的单文件可导入分发格式。

“ Python Eggs快速指南”指出:“ Eggs是Python,而Jars是Java …”

鸡蛋实际上比罐子还要丰富。它们包含有趣的元数据,例如许可详细信息,发布依赖项等。

“Egg” is a single-file importable distribution format for Python-related projects.

“The Quick Guide to Python Eggs” notes that “Eggs are to Pythons as Jars are to Java…”

Eggs actually are richer than jars; they hold interesting metadata such as licensing details, release dependencies, etc.