Làm cách nào tôi có thể bao gồm tệp YAML bên trong tệp khác?


288

Vì vậy, tôi có hai tệp YAML, "A" và "B" và tôi muốn nội dung của A được chèn vào bên trong B, được ghép vào cấu trúc dữ liệu hiện có, như một mảng hoặc là con của một phần tử, như giá trị cho một khóa băm nhất định.

cái này nó có hoàn toàn có thể xảy ra được không? Làm sao? Nếu không, bất kỳ con trỏ đến một tài liệu tham khảo quy chuẩn?



1
Gần đây tôi đã tình cờ gặp HiYaPyCo cho Python thực hiện chính xác điều này. Bạn có thể hợp nhất các tệp YAML khác nhau lại với nhau. Là một mô-đun Python rất đẹp mà đáng để biết.
nowox

Câu trả lời:


326

Không, YAML không bao gồm bất kỳ loại tuyên bố "nhập khẩu" hoặc "bao gồm" nào.


8
Bạn có thể tạo trình xử lý! Bao gồm <filename>.
clarkevans

5
@clarkevans chắc chắn, nhưng cấu trúc đó sẽ "nằm ngoài" ngôn ngữ YAML.
jameshfisher

2
Điều này bây giờ có thể. Tôi đã thêm một câu trả lời dưới đây ... hy vọng nó sẽ giúp.
daveaspinall

1
Nếu bạn đang sử dụng Rails, bạn có thể chèn cú pháp <% = 'fdsa fdsa'%> ERB và nó sẽ hoạt động
gleenn

9
Tôi nghĩ rằng câu trả lời này nên được đánh giá lại là "Không, YAML tiêu chuẩn không bao gồm chức năng này. Tuy nhiên, nhiều triển khai cung cấp một số phần mở rộng để làm như vậy."
Franklin Yu

112

Câu hỏi của bạn không yêu cầu giải pháp Python, nhưng đây là câu hỏi sử dụng PyYAML .

PyYAML cho phép bạn đính kèm các hàm tạo tùy chỉnh (như !include) vào trình tải YAML. Tôi đã bao gồm một thư mục gốc có thể được đặt để giải pháp này hỗ trợ các tham chiếu tệp tương đối và tuyệt đối.

Giải pháp dựa trên lớp học

Đây là một giải pháp dựa trên lớp, giúp tránh biến gốc toàn cầu của phản ứng ban đầu của tôi.

Xem ý chính này để biết giải pháp Python 3 tương tự, mạnh mẽ hơn, sử dụng siêu dữ liệu để đăng ký hàm tạo tùy chỉnh.

import yaml
import os

class Loader(yaml.SafeLoader):

    def __init__(self, stream):

        self._root = os.path.split(stream.name)[0]

        super(Loader, self).__init__(stream)

    def include(self, node):

        filename = os.path.join(self._root, self.construct_scalar(node))

        with open(filename, 'r') as f:
            return yaml.load(f, Loader)

Loader.add_constructor('!include', Loader.include)

Một ví dụ:

foo.yaml

a: 1
b:
    - 1.43
    - 543.55
c: !include bar.yaml

bar.yaml

- 3.6
- [1, 2, 3]

Bây giờ các tập tin có thể được tải bằng cách sử dụng:

>>> with open('foo.yaml', 'r') as f:
>>>    data = yaml.load(f, Loader)
>>> data
{'a': 1, 'b': [1.43, 543.55], 'c': [3.6, [1, 2, 3]]}

Đây là một tính năng hấp dẫn, thanx. Nhưng mục đích của tất cả các thao tác này với root / old_root là gì? Tôi giả sử mã của includehàm có thể đơn giản hóa: `def bao gồm (trình tải, nút):" "" Bao gồm một tệp YAML khác. "" "Filename = loader.construct_scalar (nút) data = yaml.load (mở (tên tệp))`
Aliaksei Ramanau

Toàn cầu gốc có ở đó sao cho tương đối bao gồm công việc ở bất kỳ độ sâu nào, ví dụ: khi các tệp được bao gồm trong một thư mục khác bao gồm một tệp liên quan đến thư mục đó. Tuyệt đối bao gồm nên làm việc, quá. Có lẽ có một cách sạch hơn để làm điều này mà không cần biến toàn cục, có lẽ sử dụng lớp yaml.Loader tùy chỉnh.
Josh Bode

2
Có phải cũng có thể có một cái gì đó như thế này: foo.yaml: a: bla bar.yaml: `! Bao gồm foo.yaml b: blubb` Vì vậy, kết quả sẽ là:` {'a': bla, 'b': blubb}
Martin

3
Đây phải là câu trả lời được chấp nhận. Ngoài ra, một nitlog bảo mật, bạn nên sử dụng yaml.safeload thay vì yaml.load, để tránh yaml được chế tạo đặc biệt từ việc sở hữu dịch vụ của bạn.
danielpops

1
@JoshBode cái này sẽ phù hợp với bạn: gist.github.com/danielpops/5a0726f2fb6288da749c4cd604276be8
danielpops

32

Nếu bạn đang sử dụng phiên bản YAML của Symfony , điều này là có thể, như thế này:

imports:
    - { resource: sub-directory/file.yml }
    - { resource: sub-directory/another-file.yml }

34
Điều này đặc trưng cho cách Symfony diễn giải YAML, chứ không phải là một phần của chính YAML.
jameshfisher

9
Đúng, đó là lý do tại sao tôi đăng liên kết tới tài liệu Symfony. Câu hỏi đặt ra "Điều này có khả thi không? Làm thế nào?" ... đây là cách thực hiện. Xem không có lý do cho một downvote.
daveaspinall

4
Tôi đã không đánh giá thấp bạn; Tôi chỉ chỉ ra rằng điều này là dành riêng cho Symfony YAML.
jameshfisher

9
Không có "phiên bản Symfony của YAML" ... đây đơn giản là một thư viện tương thích YAML dành riêng cho nhà cung cấp có thêm nội dung không phải là một phần của YAML.
dreftymac

3
Không có lý do gì để hạ thấp câu trả lời này nếu câu trả lời "dựa trên lớp" được nâng cấp.
Mikhail

13

Bao gồm không được hỗ trợ trực tiếp trong YAML theo như tôi biết, bạn sẽ phải tự cung cấp một cơ chế, tuy nhiên, điều này thường dễ thực hiện.

Tôi đã sử dụng YAML làm ngôn ngữ cấu hình trong các ứng dụng python của mình và trong trường hợp này thường định nghĩa một quy ước như thế này:

>>> main.yml <<<
includes: [ wibble.yml, wobble.yml]

Sau đó, trong mã (python) của tôi, tôi làm:

import yaml
cfg = yaml.load(open("main.yml"))
for inc in cfg.get("includes", []):
   cfg.update(yaml.load(open(inc)))

Mặt trái duy nhất là các biến trong bao gồm sẽ luôn ghi đè các biến trong main và không có cách nào để thay đổi mức ưu tiên đó bằng cách thay đổi nơi câu lệnh "include: xuất hiện trong tệp main.yml.

Ở một khía cạnh khác, YAML không hỗ trợ bao gồm vì nó không thực sự được thiết kế độc quyền như một tệp dựa trên đánh dấu. Bao gồm có nghĩa là gì nếu bạn nhận được phản hồi cho yêu cầu AJAX?


3
Điều này chỉ hoạt động khi tệp yaml không chứa cấu hình lồng nhau.
Tự do

10

Đối với người dùng Python, bạn có thể dùng thử pyyaml-include .

Tải về

pip install pyyaml-include

Sử dụng

import yaml
from yamlinclude import YamlIncludeConstructor

YamlIncludeConstructor.add_to_loader_class(loader_class=yaml.FullLoader, base_dir='/your/conf/dir')

with open('0.yaml') as f:
    data = yaml.load(f, Loader=yaml.FullLoader)

print(data)

Hãy xem xét chúng tôi có các tệp YAML như vậy :

├── 0.yaml
└── include.d
    ├── 1.yaml
    └── 2.yaml
  • 1.yaml Nội dung của:
name: "1"
  • 2.yaml Nội dung của:
name: "2"

Bao gồm các tệp theo tên

  • Ở cấp độ cao nhất:

    Nếu 0.yamllà:

!include include.d/1.yaml

Chúng tôi sẽ nhận được:

{"name": "1"}
  • Trong ánh xạ:

    Nếu 0.yamllà:

file1: !include include.d/1.yaml
file2: !include include.d/2.yaml

Chúng tôi sẽ nhận được:

  file1:
    name: "1"
  file2:
    name: "2"
  • Theo thứ tự:

    Nếu 0.yamllà:

files:
  - !include include.d/1.yaml
  - !include include.d/2.yaml

Chúng tôi sẽ nhận được:

files:
  - name: "1"
  - name: "2"

Lưu ý :

Tên tệp có thể là tuyệt đối (như /usr/conf/1.5/Make.yml) hoặc tương đối (như ../../cfg/img.yml).

Bao gồm các tệp bằng ký tự đại diện

Tên tệp có thể chứa ký tự đại diện kiểu vỏ. Dữ liệu được tải từ (các) tệp được tìm thấy bởi các ký tự đại diện sẽ được đặt theo trình tự.

Nếu 0.yamllà:

files: !include include.d/*.yaml

Chúng tôi sẽ nhận được:

files:
  - name: "1"
  - name: "2"

Lưu ý :

  • Đối với Python>=3.5, nếu recursiveđối số của thẻ !include YAMLtrue, mẫu “**”sẽ khớp với bất kỳ tệp nào và không hoặc nhiều thư mục và thư mục con.
  • Sử dụng “**”mẫu trong các cây thư mục lớn có thể tiêu tốn một lượng thời gian không phù hợp vì tìm kiếm đệ quy.

Để bật recursiveđối số, chúng tôi sẽ ghi !includethẻ vào Mappinghoặc Sequencechế độ:

  • Đối số trong Sequencechế độ:
!include [tests/data/include.d/**/*.yaml, true]
  • Đối số trong Mappingchế độ:
!include {pathname: tests/data/include.d/**/*.yaml, recursive: true}

Điều này không thực sự trả lời câu hỏi. Nó liên quan đến một giải pháp Python, không phải là một giải pháp sử dụng định dạng YAML được tiêu chuẩn hóa.
oligofren

@oligofren Trình xử lý thẻ tùy chỉnh là một tính năng của YAML, cho phép trình phân tích cú pháp mở rộng YAML để chỉ định các loại và thực hiện các hành vi tùy chỉnh như thế này. Bản thân thông số kỹ thuật YAML sẽ kéo dài đến mức quy định cách bao gồm tệp nên hoạt động với tất cả các thông số đường dẫn hệ điều hành khác nhau, hệ thống tệp, v.v.
Anton Strogonoff

@AntonStrogonoff Cảm ơn bạn đã chú ý đến điều đó. Bạn có thể chỉ cho tôi một nơi như vậy trong RFC? Nó không có đề cập đến từ "tùy chỉnh". Tham khảo yaml.org/spec/1.2/spec.html
oligofren

1
@oligofren Bạn được chào đón. Hãy tìm các thẻ thành phần cụ thể của ứng dụng .
Anton Strogonoff

8

Mở rộng câu trả lời của @ Josh_Bode, đây là giải pháp PyYAML của riêng tôi, có lợi thế là một lớp con khép kín của yaml.Loader. Nó không phụ thuộc vào bất kỳ toàn cầu cấp mô-đun, hoặc vào việc sửa đổi trạng thái toàn cầu của yamlmô-đun.

import yaml, os

class IncludeLoader(yaml.Loader):                                                 
    """                                                                           
    yaml.Loader subclass handles "!include path/to/foo.yml" directives in config  
    files.  When constructed with a file object, the root path for includes       
    defaults to the directory containing the file, otherwise to the current       
    working directory. In either case, the root path can be overridden by the     
    `root` keyword argument.                                                      

    When an included file F contain its own !include directive, the path is       
    relative to F's location.                                                     

    Example:                                                                      
        YAML file /home/frodo/one-ring.yml:                                       
            ---                                                                   
            Name: The One Ring                                                    
            Specials:                                                             
                - resize-to-wearer                                                
            Effects: 
                - !include path/to/invisibility.yml                            

        YAML file /home/frodo/path/to/invisibility.yml:                           
            ---                                                                   
            Name: invisibility                                                    
            Message: Suddenly you disappear!                                      

        Loading:                                                                  
            data = IncludeLoader(open('/home/frodo/one-ring.yml', 'r')).get_data()

        Result:                                                                   
            {'Effects': [{'Message': 'Suddenly you disappear!', 'Name':            
                'invisibility'}], 'Name': 'The One Ring', 'Specials':              
                ['resize-to-wearer']}                                             
    """                                                                           
    def __init__(self, *args, **kwargs):                                          
        super(IncludeLoader, self).__init__(*args, **kwargs)                      
        self.add_constructor('!include', self._include)                           
        if 'root' in kwargs:                                                      
            self.root = kwargs['root']                                            
        elif isinstance(self.stream, file):                                       
            self.root = os.path.dirname(self.stream.name)                         
        else:                                                                     
            self.root = os.path.curdir                                            

    def _include(self, loader, node):                                    
        oldRoot = self.root                                              
        filename = os.path.join(self.root, loader.construct_scalar(node))
        self.root = os.path.dirname(filename)                           
        data = yaml.load(open(filename, 'r'))                            
        self.root = oldRoot                                              
        return data                                                      

2
Cuối cùng cũng có cách thêm cách tiếp cận dựa trên lớp vào câu trả lời của tôi, nhưng bạn đánh tôi tới cú đấm :) Lưu ý: Nếu bạn sử dụng yaml.load(f, IncludeLoader)bên trong _includebạn có thể tránh phải thay thế root. Ngoài ra, trừ khi bạn làm điều này, giải pháp sẽ không hoạt động sâu hơn một cấp vì dữ liệu đi kèm sử dụng yaml.Loaderlớp thông thường .
Josh Bode

Tôi đã phải loại bỏ các từ khóa rootcủa kwargssau khi cài đặt self.rootđể có được nó làm việc với chuỗi. Tôi di chuyển khối if-other phía trên supercuộc gọi. Có lẽ ai đó khác có thể xác nhận phát hiện của tôi hoặc chỉ cho tôi cách sử dụng lớp với chuỗi và roottham số.
Woltan

1
Thật không may, điều này không hoạt động với các tham chiếu như `` `bao gồm: & BAO GỒM! Bao gồm cả nội địa.yaml hợp nhất: <<: * BAO GỒM` ``
antony

2

Tôi làm một số ví dụ để bạn tham khảo.

import yaml

main_yaml = """
Package:
 - !include _shape_yaml    
 - !include _path_yaml
"""

_shape_yaml = """
# Define
Rectangle: &id_Rectangle
    name: Rectangle
    width: &Rectangle_width 20
    height: &Rectangle_height 10
    area: !product [*Rectangle_width, *Rectangle_height]

Circle: &id_Circle
    name: Circle
    radius: &Circle_radius 5
    area: !product [*Circle_radius, *Circle_radius, pi]

# Setting
Shape:
    property: *id_Rectangle
    color: red
"""

_path_yaml = """
# Define
Root: &BASE /path/src/

Paths: 
    a: &id_path_a !join [*BASE, a]
    b: &id_path_b !join [*BASE, b]

# Setting
Path:
    input_file: *id_path_a
"""


# define custom tag handler
def yaml_import(loader, node):
    other_yaml_file = loader.construct_scalar(node)
    return yaml.load(eval(other_yaml_file), Loader=yaml.SafeLoader)


def yaml_product(loader, node):
    import math
    list_data = loader.construct_sequence(node)
    result = 1
    pi = math.pi
    for val in list_data:
        result *= eval(val) if isinstance(val, str) else val
    return result


def yaml_join(loader, node):
    seq = loader.construct_sequence(node)
    return ''.join([str(i) for i in seq])


def yaml_ref(loader, node):
    ref = loader.construct_sequence(node)
    return ref[0]


def yaml_dict_ref(loader: yaml.loader.SafeLoader, node):
    dict_data, key, const_value = loader.construct_sequence(node)
    return dict_data[key] + str(const_value)


def main():
    # register the tag handler
    yaml.SafeLoader.add_constructor(tag='!include', constructor=yaml_import)
    yaml.SafeLoader.add_constructor(tag='!product', constructor=yaml_product)
    yaml.SafeLoader.add_constructor(tag='!join', constructor=yaml_join)
    yaml.SafeLoader.add_constructor(tag='!ref', constructor=yaml_ref)
    yaml.SafeLoader.add_constructor(tag='!dict_ref', constructor=yaml_dict_ref)

    config = yaml.load(main_yaml, Loader=yaml.SafeLoader)

    pk_shape, pk_path = config['Package']
    pk_shape, pk_path = pk_shape['Shape'], pk_path['Path']
    print(f"shape name: {pk_shape['property']['name']}")
    print(f"shape area: {pk_shape['property']['area']}")
    print(f"shape color: {pk_shape['color']}")

    print(f"input file: {pk_path['input_file']}")


if __name__ == '__main__':
    main()

đầu ra

shape name: Rectangle
shape area: 200
shape color: red
input file: /path/src/a

Cập nhật 2

và bạn có thể kết hợp nó, như thế này

# xxx.yaml
CREATE_FONT_PICTURE:
  PROJECTS:
    SUNG: &id_SUNG
      name: SUNG
      work_dir: SUNG
      output_dir: temp
      font_pixel: 24


  DEFINE: &id_define !ref [*id_SUNG]  # you can use config['CREATE_FONT_PICTURE']['DEFINE'][name, work_dir, ... font_pixel]
  AUTO_INIT:
    basename_suffix: !dict_ref [*id_define, name, !product [5, 3, 2]]  # SUNG30

# ↓ This is not correct.
# basename_suffix: !dict_ref [*id_define, name, !product [5, 3, 2]]  # It will build by Deep-level. id_define is Deep-level: 2. So you must put it after 2. otherwise, it can't refer to the correct value.


1

Tôi nghĩ rằng giải pháp được sử dụng bởi @ maxy-B trông rất tuyệt. Tuy nhiên, nó đã không thành công đối với tôi với các thể vùi lồng nhau. Ví dụ: nếu config_1.yaml bao gồm config_2.yaml, bao gồm config_3.yaml có vấn đề với trình tải. Tuy nhiên, nếu bạn chỉ đơn giản trỏ lớp trình nạp mới vào chính nó khi tải, thì nó hoạt động! Cụ thể, nếu chúng ta thay thế hàm _incoide cũ bằng phiên bản sửa đổi rất ít:

def _include(self, loader, node):                                    
     oldRoot = self.root                                              
     filename = os.path.join(self.root, loader.construct_scalar(node))
     self.root = os.path.dirname(filename)                           
     data = yaml.load(open(filename, 'r'), loader = IncludeLoader)                            
     self.root = oldRoot                                              
     return data

Sau khi phản ánh, tôi đồng ý với các ý kiến ​​khác, việc tải lồng nhau không phù hợp với yaml nói chung vì luồng đầu vào có thể không phải là một tệp, nhưng nó rất hữu ích!


1

Tiêu chuẩn YML không chỉ định một cách để làm điều này. Và vấn đề này không giới hạn ở YML. JSON có những hạn chế tương tự.

Cuối cùng, nhiều ứng dụng sử dụng cấu hình dựa trên YML hoặc JSON cũng gặp phải vấn đề này. Và khi điều đó xảy ra, họ tạo nên quy ước của riêng họ .

ví dụ: đối với các định nghĩa API vênh vang:

$ref: 'file.yml'

ví dụ: đối với cấu hình docker compose:

services:
  app:
    extends:
      file: docker-compose.base.yml

Ngoài ra, nếu bạn muốn tách nội dung của tệp yml thành nhiều tệp, như một cây nội dung, bạn có thể xác định quy ước cấu trúc thư mục của riêng mình và sử dụng tập lệnh hợp nhất (hiện có).



0

Tiêu chuẩn YAML 1.2 không bao gồm tính năng này. Tuy nhiên, nhiều triển khai cung cấp một số phần mở rộng để làm như vậy.

Tôi trình bày một cách để đạt được nó với Java và snakeyaml:1.24(thư viện Java để phân tích / phát ra các tệp YAML) cho phép tạo thẻ YAML tùy chỉnh để đạt được mục tiêu sau (bạn sẽ thấy tôi đang sử dụng nó để tải các bộ kiểm tra được xác định trong một số tệp YAML và tôi đã làm cho nó hoạt động như một danh sách bao gồm cho một test:nút đích ):

# ... yaml prev stuff

tests: !include
  - '1.hello-test-suite.yaml'
  - '3.foo-test-suite.yaml'
  - '2.bar-test-suite.yaml'

# ... more yaml document

Đây là Java một lớp cho phép xử lý !includethẻ. Các tệp được tải từ classpath (thư mục tài nguyên Maven):

/**
 * Custom YAML loader. It adds support to the custom !include tag which allows splitting a YAML file across several
 * files for a better organization of YAML tests.
 */
@Slf4j   // <-- This is a Lombok annotation to auto-generate logger
public class MyYamlLoader {

    private static final Constructor CUSTOM_CONSTRUCTOR = new MyYamlConstructor();

    private MyYamlLoader() {
    }

    /**
     * Parse the only YAML document in a stream and produce the Java Map. It provides support for the custom !include
     * YAML tag to split YAML contents across several files.
     */
    public static Map<String, Object> load(InputStream inputStream) {
        return new Yaml(CUSTOM_CONSTRUCTOR)
                .load(inputStream);
    }


    /**
     * Custom SnakeYAML constructor that registers custom tags.
     */
    private static class MyYamlConstructor extends Constructor {

        private static final String TAG_INCLUDE = "!include";

        MyYamlConstructor() {
            // Register custom tags
            yamlConstructors.put(new Tag(TAG_INCLUDE), new IncludeConstruct());
        }

        /**
         * The actual include tag construct.
         */
        private static class IncludeConstruct implements Construct {

            @Override
            public Object construct(Node node) {
                List<Node> inclusions = castToSequenceNode(node);
                return parseInclusions(inclusions);
            }

            @Override
            public void construct2ndStep(Node node, Object object) {
                // do nothing
            }

            private List<Node> castToSequenceNode(Node node) {
                try {
                    return ((SequenceNode) node).getValue();

                } catch (ClassCastException e) {
                    throw new IllegalArgumentException(String.format("The !import value must be a sequence node, but " +
                            "'%s' found.", node));
                }
            }

            private Object parseInclusions(List<Node> inclusions) {

                List<InputStream> inputStreams = inputStreams(inclusions);

                try (final SequenceInputStream sequencedInputStream =
                             new SequenceInputStream(Collections.enumeration(inputStreams))) {

                    return new Yaml(CUSTOM_CONSTRUCTOR)
                            .load(sequencedInputStream);

                } catch (IOException e) {
                    log.error("Error closing the stream.", e);
                    return null;
                }
            }

            private List<InputStream> inputStreams(List<Node> scalarNodes) {
                return scalarNodes.stream()
                        .map(this::inputStream)
                        .collect(toList());
            }

            private InputStream inputStream(Node scalarNode) {
                String filePath = castToScalarNode(scalarNode).getValue();
                final InputStream is = getClass().getClassLoader().getResourceAsStream(filePath);
                Assert.notNull(is, String.format("Resource file %s not found.", filePath));
                return is;
            }

            private ScalarNode castToScalarNode(Node scalarNode) {
                try {
                    return ((ScalarNode) scalarNode);

                } catch (ClassCastException e) {
                    throw new IllegalArgumentException(String.format("The value must be a scalar node, but '%s' found" +
                            ".", scalarNode));
                }
            }
        }

    }

}

0

Với Yglu , bạn có thể nhập các tệp khác như thế này:

A.yaml

foo: !? $import('B.yaml')

B.yaml

bar: Hello
$ yglu A.yaml
foo:
  bar: Hello

$importmột hàm, bạn cũng có thể truyền một biểu thức dưới dạng đối số:

  dep: !- b
  foo: !? $import($_.dep.toUpper() + '.yaml')

Điều này sẽ cho đầu ra tương tự như trên.

Tuyên bố miễn trừ trách nhiệm: Tôi là tác giả của Yglu.


-1

Với Symfony , việc xử lý yaml của nó sẽ gián tiếp cho phép bạn lồng các tệp yaml. Bí quyết là sử dụng parameterstùy chọn. ví dụ:

chung.yml

parameters:
    yaml_to_repeat:
        option: "value"
        foo:
            - "bar"
            - "baz"

config.yml

imports:
    - { resource: common.yml }
whatever:
    thing: "%yaml_to_repeat%"
    other_thing: "%yaml_to_repeat%"

Kết quả sẽ giống như:

whatever:
    thing:
        option: "value"
        foo:
            - "bar"
            - "baz"
    other_thing:
        option: "value"
        foo:
            - "bar"
            - "baz"

-6

Có thể nó không được hỗ trợ khi câu hỏi được hỏi nhưng bạn có thể nhập tệp YAML khác vào một:

imports: [/your_location_to_yaml_file/Util.area.yaml]

Mặc dù tôi không có bất kỳ tài liệu tham khảo trực tuyến nào nhưng điều này hiệu quả với tôi.


4
Điều này không làm gì bao gồm cả. Nó tạo ra một ánh xạ với một chuỗi bao gồm một chuỗi "/your_location_to_yaml_file/Util.area.yaml", làm giá trị cho khóa imports.
Anthon
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.