init()¶
这是一个用于初始化 conanfile 值的可选方法,专为从 python_requires
继承而设计。 假设我们有一个 base/1.1
配方
from conan import ConanFile
class MyConanfileBase:
license = "MyLicense"
settings = "os", # tuple!
class PyReq(ConanFile):
name = "base"
version = "1.1"
package_type = "python-require"
我们可以使用它并从中继承:
from conan import ConanFile
class Pkg(ConanFile):
license = "MIT"
settings = "arch", # tuple!
python_requires = "base/1.1"
python_requires_extend = "base.MyConanfileBase"
def init(self):
base = self.python_requires["base"].module.MyConanfileBase
self.settings = base.settings + self.settings # Note, adding 2 tuples = tuple
self.license = base.license # License is overwritten
最终的 Pkg
conanfile 将同时具有 os
和 arch
作为 settings,并具有 MyLicense
作为 license。
为了扩展基类的 options
,需要调用 self.options.update()
方法
from conan import ConanFile
class BaseConan:
options = {"base": [True, False]}
default_options = {"base": True}
class PyReq(ConanFile):
name = "base"
version = "1.0.0"
package_type = "python-require"
当调用 init()
时,self.options
对象已经被初始化。 那么,更新 self.default_options
是无用的,并且有必要使用基类选项和基类默认选项值来更新 self.options
from conan import ConanFile
class DerivedConan(ConanFile):
name = "derived"
python_requires = "base/1.0.0"
python_requires_extend = "base.BaseConan"
options = {"derived": [True, False]}
default_options = {"derived": False}
def init(self):
base = self.python_requires["base"].module.BaseConan
# Note we pass the base options and default_options
self.options.update(base.options, base.default_options)
如果您需要无条件地初始化类属性,如 license
或 description
或来自 conandata.yml 之外的数据文件的任何其他属性,此方法也很有用。 例如,您可以有一个 json 文件,其中包含有关库的 license
,description
和 author
的信息
{"license": "MIT", "description": "This is my awesome library.", "author": "Me"}
然后,您可以从 init()
方法加载该信息
import os
import json
from conan import ConanFile
from conan.tools.files import load
class Pkg(ConanFile):
exports = "data.json" # Important that it is exported with the recipe
def init(self):
data = load(self, os.path.join(self.recipe_folder, "data.json"))
d = json.loads(data)
self.license = d["license"]
self.description = d["description"]
self.author = d["author"]
注意
最佳实践
尽量保持您的
python_requires
尽可能简单,并且不要重用它们的属性(init()
方法的主要需求),尽量避免这种init()
方法的复杂性。 一般来说,继承可能比组合有更多的问题(或者换句话说,“使用组合而不是继承”作为一般的编程良好实践),所以如果可能的话,尽量避免它。不要滥用
init()
用于此处列出的目的之外的其他目的,也不要使用 Python 私有ConanFile.__init__
构造函数。init()
方法在配方加载时执行。 它不能包含设置、选项、conf 的条件,也不能使用除上述python_requires
之外的任何依赖项信息。