gym的space翻译

Spaces

This module implements various spaces.

Spaces describe mathematical sets and are used in Gym to specify valid actions and observations. Every Gym environment must have the attributes action_space and observation_space. If, for instance, three possible actions (0,1,2) can be performed in your environment and observations are vectors in the two-dimensional unit cube, the environment code may contain the following two lines:该模块实现了各种空间。
空间描述数学集合,并在健身房中用于指定有效的动作和观察。每个健身房环境都必须具有action_space和observation_space属性。例如,如果可以在您的环境中执行三个可能的操作(0,1,2),并且观测值是二维单位立方体中的向量,则环境代码可能包含以下两行:

self.action_space = spaces.Discrete(3)
self.observation_space = spaces.Box(0, 1, shape=(2,))

All spaces inherit from the Space superclass.

class gymnasium.spaces.Space(shape: Sequence[int] | None = Nonedtype: npt.DTypeLike | None = Noneseed: int | np.random.Generator | None = None)

Superclass that is used to define observation and action spaces.

Spaces are crucially used in Gym to define the format of valid actions and observations. They serve various purposes:

  • They clearly define how to interact with environments, i.e. they specify what actions need to look like and what observations will look like

  • They allow us to work with highly structured data (e.g. in the form of elements of Dict spaces) and painlessly transform them into flat arrays that can be used in learning code

  • They provide a method to sample random elements. This is especially useful for exploration and debugging.​
    用于定义观察空间和动作空间的超类。
    空间在gym中至关重要,用来定义有效动作和观察的形式。它们有多种用途:

Different spaces can be combined hierarchically via container spaces (Tuple and Dict) to build a more expressive space

Warning

Custom observation & action spaces can inherit from the Space class. However, most use-cases should be covered by the existing space classes (e.g. BoxDiscrete, etc…), and container classes (:class`Tuple` & Dict). Note that parametrized probability distributions (through the Space.sample() method), and batching functions (in gym.vector.VectorEnv), are only well-defined for instances of spaces provided in gym by default. Moreover, some implementations of Reinforcement Learning algorithms might not handle custom spaces properly. Use custom spaces with care.​
自定义观察和操作空间可以从Space类继承。然而,大多数用例应该由现有的空间类(例如Box、Discrete等)和容器类(:class `Tuple`&Dict)覆盖。请注意,参数化概率分布(通过Space.sample()方法)和批处理函数(在gym.vector.VvectorEnv中)仅在默认情况下为gym中提供的空间实例定义。此外,强化学习算法的一些实现可能无法正确处理自定义空间。小心使用自定义空间。

PARAMETERS:

  • shape (Optional[Sequence[int]]) – If elements of the space are numpy arrays, this should specify their shape.

  • dtype (Optional[Type | str]) – If elements of the space are numpy arrays, this should specify their dtype.

  • seed – Optionally, you can use this argument to seed the RNG that is used to sample from the space

Attributes

property Space.shape: tuple[int, ...] | None

Return the shape of the space as an immutable property.

property Space.dtype

Return the data type of this space.

property Space.is_np_flattenable: bool

Checks whether this space can be flattened to a gymnasium.spaces.Box.

Methods

Each space implements the following functions:

gymnasium.spaces.space.Space.sample(selfmask: Any | None = None) → T_cov

Randomly sample an element of this space.

Can be uniform or non-uniform sampling based on boundedness of space.

PARAMETERS:

mask – A mask used for sampling, expected dtype=np.int8 and see sample implementation for expected shape.

RETURNS:

A sampled actions from the space

gymnasium.spaces.space.Space.contains(selfx: Any) → bool

Return boolean specifying if x is a valid member of this space.

gymnasium.spaces.space.Space.seed(selfseed: int | None = None) → list[int]

Seed the PRNG of this space and possibly the PRNGs of subspaces.

gymnasium.spaces.space.Space.to_jsonable(selfsample_n: Sequence[T_cov]) → list[Any]

Convert a batch of samples from this space to a JSONable data type.

gymnasium.spaces.space.Space.from_jsonable(selfsample_n: list[Any]) → list[+T_cov]

Convert a JSONable data type to a batch of samples from this space.

Fundamental Spaces

Gymnasium has a number of fundamental spaces that are used as building boxes for more complex spaces.gym有许多基本空间,用作更复杂空间的建筑箱

  • Box - Supports continuous (and discrete) vectors or matrices, used for vector observations, images, etc

  • Discrete - Supports a single discrete number of values with an optional start for the values

  • MultiBinary - Supports single or matrices of binary values, used for holding down a button or if an agent has an object支持二进制值的单个或矩阵,用于按住按钮或代理有对象时

  • MultiDiscrete - Supports multiple discrete values with multiple axes, used for controller actions

  • Text - Supports strings, used for passing agent messages, mission details, etc

Composite Spaces

Often environment spaces require joining fundamental spaces together for vectorised environments, separate agents or readability of the space.环境空间通常需要将基本空间连接在一起,以实现矢量化环境、独立代理或空间的可读性。

  • Dict - Supports a dictionary of keys and subspaces, used for a fixed number of unordered spaces支持键和子空间的字典,用于固定数量的无序空间

  • Tuple - Supports a tuple of subspaces, used for multiple for a fixed number of ordered spaces

  • Sequence - Supports a variable number of instances of a single subspace, used for entities spaces or selecting a variable number of actions支持单个子空间的可变数量的实例,用于实体空间或选择可变数量的操作

  • Graph - Supports graph based actions or observations with discrete or continuous nodes and edge values.支持具有离散或连续节点和边值的基于图形的操作或观察

Utils

Gymnasium contains a number of helpful utility functions for flattening and unflattening spaces. This can be important for passing information to neural networks.体育馆包含许多有用的实用功能,用于平整和不平整空间。这对于将信息传递给神经网络非常重要。

  • utils.flatdim - The number of dimensions the flattened space will contain

  • utils.flatten_space - Flattens a space for which the flattened space instances will contain

  • utils.flatten - Flattens an instance of a space that is contained within the flattened version of the space

  • utils.unflatten - The reverse of the flatten_space function

Vector Utils

When vectorizing environments, it is necessary to modify the observation and action spaces for new batched spaces sizes. Therefore, Gymnasium provides a number of additional functions used when using a space with a Vector environment.

Fundamental Spaces

Box

class gymnasium.spaces.Box(low: SupportsFloat | NDArray[Any]high: SupportsFloat | NDArray[Any]shape: Sequence[int] | None = Nonedtype: type[np.floating[Any]] | type[np.integer[Any]] = np.float32seed: int | np.random.Generator | None = None)

\([a, \infty)\), or \((-\infty, \infty)\).

There are two common use cases:

有两种常见的用例

  • Identical bound for each dimension:

    >>> Box(low=-1.0, high=2.0, shape=(3, 4), dtype=np.float32)
    Box(-1.0, 2.0, (3, 4), float32)
    
  • Independent bound for each dimension:

    >>> Box(low=np.array([-1.0, -2.0]), high=np.array([2.0, 4.0]), dtype=np.float32)
    Box([-1. -2.], [2. 4.], (2,), float32)
    

PARAMETERS:

  • low (SupportsFloat | np.ndarray) – Lower bounds of the intervals. If integer, must be at least -2**63.

  • high (SupportsFloat | np.ndarray]) – Upper bounds of the intervals. If integer, must be at most 2**63 - 2.

  • shape (Optional[Sequence[int]]) – The shape is inferred from the shape of low or high np.ndarray`s with `low and high scalars defaulting to a shape of (1,)

  • dtype – The dtype of the elements of the space. If this is an integer type, the Box is essentially a discrete space.

  • seed – Optionally, you can use this argument to seed the RNG that is used to sample from the space.

RAISES:

ValueError – If no shape information is provided (shape is None, low is None and high is None) then a value error is raised.

Box.sample(mask: None = None) → ndarray[Any, dtype[Any]]

Generates a single random sample inside the Box.

In creating a sample of the box, each coordinate is sampled (independently) from a distribution that is chosen according to the form of the interval:在长方体内部生成单个随机采样。
在创建长方体的样本时,每个坐标都是从根据间隔形式选择的分布中(独立地)采样的:

  • \([a, b]\) : uniform distribution

  • \([a, \infty)\) : shifted exponential distribution

  • \((-\infty, b]\) : shifted negative exponential distribution

  • \((-\infty, \infty)\) : normal distribution

PARAMETERS:

mask – A mask for sampling values from the Box space, currently unsupported.

RETURNS:

A sampled value from the Box

Box.seed(seed: int | None = None) → list[int]

Seed the PRNG of this space and possibly the PRNGs of subspaces.

Box.is_bounded(manner: str = 'both') → bool

Checks whether the box is bounded in some sense.

PARAMETERS:

manner (str) – One of "both""below""above".

RETURNS:

If the space is bounded

RAISES:

ValueError – If manner is neither "both" nor "below" or "above"

Discrete

class gymnasium.spaces.Discrete(n: int | np.integer[Any]seed: int | np.random.Generator | None = Nonestart: int | np.integer[Any] = 0)

A space consisting of finitely many elements.

This class represents a finite subset of integers, more specifically a set of the form \(\{ a, a+1, \dots, a+n-1 \}\).
由有限多个元素组成的空间。
这个类表示整数的有限子集,更具体地说是形式为\(\{a,a+1,\dots,a+n-1 \}\)的集合。

EXAMPLE

>>> from gymnasium.spaces import Discrete
>>> observation_space = Discrete(2, seed=42) # {0, 1}
>>> observation_space.sample()
0
>>> observation_space = Discrete(3, start=-1, seed=42)  # {-1, 0, 1}
>>> observation_space.sample()
-1

PARAMETERS:

  • n (int) – The number of elements of this space.

  • seed – Optionally, you can use this argument to seed the RNG that is used to sample from the Dict space.

  • start (int) – The smallest element of this space.

Discrete.sample(mask: MaskNDArray | None = None) → np.int64

Generates a single random sample from this space.

A sample will be chosen uniformly at random with the mask if provided从该空间生成单个随机采样。如果提供掩模,将随机均匀选择样品。

PARAMETERS:

mask – An optional mask for if an action can be selected. Expected np.ndarray of shape (n,) and dtype np.int8 where 1 represents valid actions and 0 invalid / infeasible actions. If there are no possible actions (i.e. np.all(mask == 0)) then space.start will be returned.

RETURNS:

A sampled integer from the space

Discrete.seed(seed: int | None = None) → list[int]

Seed the PRNG of this space and possibly the PRNGs of subspaces.

MultiBinary

class gymnasium.spaces.MultiBinary(n: NDArray[np.integer[Any]] | Sequence[int] | intseed: int | np.random.Generator | None = None)

An n-shape binary space.

Elements of this space are binary arrays of a shape that is fixed during construction.

EXAMPLE

>>> from gymnasium.spaces import MultiBinary
>>> observation_space = MultiBinary(5, seed=42)
>>> observation_space.sample()
array([1, 0, 1, 0, 1], dtype=int8)
>>> observation_space = MultiBinary([3, 2], seed=42)
>>> observation_space.sample()
array([[1, 0],
       [1, 0],
       [1, 1]], dtype=int8)

PARAMETERS:

  • n – This will fix the shape of elements of the space. It can either be an integer (if the space is flat) or some sort of sequence (tuple, list or np.ndarray) if there are multiple axes.

  • seed – Optionally, you can use this argument to seed the RNG that is used to sample from the space.

MultiBinary.sample(mask: MaskNDArray | None = None) → NDArray[np.int8]

Generates a single random sample from this space.

A sample is drawn by independent, fair coin tosses (one toss per binary variable of the space).

PARAMETERS:

mask – An optional np.ndarray to mask samples with expected shape of space.shape. For mask == 0 then the samples will be 0 and mask == 1 then random samples will be generated. The expected mask shape is the space shape and mask dtype is np.int8.

RETURNS:

Sampled values from space

MultiBinary.seed(seed: int | None = None) → list[int]

Seed the PRNG of this space and possibly the PRNGs of subspaces.

MultiDiscrete

class gymnasium.spaces.MultiDiscrete(nvec: NDArray[np.integer[Any]] | list[int]dtype: str | type[np.integer[Any]] = np.int64seed: int | np.random.Generator | None = None)

This represents the cartesian product of arbitrary Discrete spaces.

It is useful to represent game controllers or keyboards where each key can be represented as a discrete action space.

Note

Some environment wrappers assume a value of 0 always represents the NOOP action.

e.g. Nintendo Game Controller - Can be conceptualized as 3 discrete action spaces:

  1. Arrow Keys: Discrete 5 - NOOP[0], UP[1], RIGHT[2], DOWN[3], LEFT[4] - params: min: 0, max: 4

  2. Button A: Discrete 2 - NOOP[0], Pressed[1] - params: min: 0, max: 1

  3. Button B: Discrete 2 - NOOP[0], Pressed[1] - params: min: 0, max: 1

It can be initialized as MultiDiscrete([ 5, 2, 2 ]) such that a sample might be array([3, 1, 0]).

Although this feature is rarely used, MultiDiscrete spaces may also have several axes if nvec has several axes:

EXAMPLE

>>> from gymnasium.spaces import MultiDiscrete
>>> import numpy as np
>>> observation_space = MultiDiscrete(np.array([[1, 2], [3, 4]]), seed=42)
>>> observation_space.sample()
array([[0, 0],
       [2, 2]])

PARAMETERS:

  • nvec – vector of counts of each categorical variable. This will usually be a list of integers. However, you may also pass a more complicated numpy array if you’d like the space to have several axes.

  • dtype – This should be some kind of integer type.

  • seed – Optionally, you can use this argument to seed the RNG that is used to sample from the space.

MultiDiscrete.sample(mask: tuple[MaskNDArray, ...] | None = None) → NDArray[np.integer[Any]]

Generates a single random sample this space.

PARAMETERS:

mask – An optional mask for multi-discrete, expects tuples with a np.ndarray mask in the position of each action with shape (n,) where n is the number of actions and dtype=np.int8. Only mask values == 1 are possible to sample unless all mask values for an action are 0 then the default action 0 is sampled.

RETURNS:

An `np.ndarray` of shape `space.shape`

MultiDiscrete.seed(seed: int | None = None) → list[int]

Seed the PRNG of this space and possibly the PRNGs of subspaces.

Text

class gymnasium.spaces.Text(max_length: int*min_length: int = 1charset: frozenset[str] | str = alphanumericseed: int | np.random.Generator | None = None)

A space representing a string comprised of characters from a given charset.

EXAMPLE

>>> from gymnasium.spaces import Text
>>> # {"", "B5", "hello", ...}
>>> Text(5)
Text(1, 5, characters=0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz)
>>> # {"0", "42", "0123456789", ...}
>>> import string
>>> Text(min_length = 1,
...      max_length = 10,
...      charset = string.digits)
Text(1, 10, characters=0123456789)

PARAMETERS:

  • min_length (int) – Minimum text length (in characters). Defaults to 1 to prevent empty strings.

  • max_length (int) – Maximum text length (in characters).

  • charset (Union[set]str) – Character set, defaults to the lower and upper english alphabet plus latin digits.

  • seed – The seed for sampling from the space.

Text.sample(mask: None | tuple[int | None, NDArray[np.int8] | None] = None) → str

Generates a single random sample from this space with by default a random length between min_length and max_length and sampled from the charset.

PARAMETERS:

mask – An optional tuples of length and mask for the text. The length is expected to be between the min_length and max_length otherwise a random integer between min_length and max_length is selected. For the mask, we expect a numpy array of length of the charset passed with dtype == np.int8. If the charlist mask is all zero then an empty string is returned no matter the min_length

RETURNS:

A sampled string from the space

Text.seed(seed: int | None = None) → list[int]

Seed the PRNG of this space and possibly the PRNGs of subspaces.

Composite Spaces

Dict

class gymnasium.spaces.Dict(spaces: None | dict[str, Space] | Sequence[tuple[str, Space]] = Noneseed: dict | int | np.random.Generator | None = None**spaces_kwargs: Space)

A dictionary of Space instances.

Elements of this space are (ordered) dictionaries of elements from the constituent spaces.

EXAMPLE

>>> from gymnasium.spaces import Dict, Box, Discrete
>>> observation_space = Dict({"position": Box(-1, 1, shape=(2,)), "color": Discrete(3)}, seed=42)
>>> observation_space.sample()
OrderedDict([('color', 0), ('position', array([-0.3991573 ,  0.21649833], dtype=float32))])

With a nested dict:

>>> from gymnasium.spaces import Box, Dict, Discrete, MultiBinary, MultiDiscrete
>>> Dict(  
...     {
...         "ext_controller": MultiDiscrete([5, 2, 2]),
...         "inner_state": Dict(
...             {
...                 "charge": Discrete(100),
...                 "system_checks": MultiBinary(10),
...                 "job_status": Dict(
...                     {
...                         "task": Discrete(5),
...                         "progress": Box(low=0, high=100, shape=()),
...                     }
...                 ),
...             }
...         ),
...     }
... )

It can be convenient to use Dict spaces if you want to make complex observations or actions more human-readable. Usually, it will not be possible to use elements of this space directly in learning code. However, you can easily convert Dict observations to flat arrays by using a gymnasium.wrappers.FlattenObservation wrapper. Similar wrappers can be implemented to deal with Dict actions.

PARAMETERS:

  • spaces – A dictionary of spaces. This specifies the structure of the Dict space

  • seed – Optionally, you can use this argument to seed the RNGs of the spaces that make up the Dict space.

  • **spaces_kwargs – If spaces is None, you need to pass the constituent spaces as keyword arguments, as described above.

Dict.sample(mask: dict[str, Any] | None = None) → dict[str, Any]

Generates a single random sample from this space.

The sample is an ordered dictionary of independent samples from the constituent spaces.

PARAMETERS:

mask – An optional mask for each of the subspaces, expects the same keys as the space

RETURNS:

A dictionary with the same key and sampled values from :attr:`self.spaces`

Dict.seed(seed: dict[str, Any] | int | None = None) → list[int]

Seed the PRNG of this space and all subspaces.

Depending on the type of seed, the subspaces will be seeded differently

  • None - All the subspaces will use a random initial seed

  • Int - The integer is used to seed the Dict space that is used to generate seed values for each of the subspaces. Warning, this does not guarantee unique seeds for all of the subspaces.

  • Dict - Using all the keys in the seed dictionary, the values are used to seed the subspaces. This allows the seeding of multiple composite subspaces (Dict["space": Dict[...], ...] with {"space": {...}, ...}).

PARAMETERS:

seed – An optional list of ints or int to seed the (sub-)spaces.

Tuple

class gymnasium.spaces.Tuple(spaces: Iterable[Space[Any]]seed: int | Sequence[int] | np.random.Generator | None = None)

A tuple (more precisely: the cartesian product) of Space instances.

Elements of this space are tuples of elements of the constituent spaces.

EXAMPLE

>>> from gymnasium.spaces import Tuple, Box, Discrete
>>> observation_space = Tuple((Discrete(2), Box(-1, 1, shape=(2,))), seed=42)
>>> observation_space.sample()
(0, array([-0.3991573 ,  0.21649833], dtype=float32))

PARAMETERS:

  • spaces (Iterable[Space]) – The spaces that are involved in the cartesian product.

  • seed – Optionally, you can use this argument to seed the RNGs of the spaces to ensure reproducible sampling.

Tuple.sample(mask: tuple[Any | None, ...] | None = None) → tuple[Any, ...]

Generates a single random sample inside this space.

This method draws independent samples from the subspaces.

PARAMETERS:

mask – An optional tuple of optional masks for each of the subspace’s samples, expects the same number of masks as spaces

RETURNS:

Tuple of the subspace’s samples

Tuple.seed(seed: int | Sequence[int] | None = None) → list[int]

Seed the PRNG of this space and all subspaces.

Depending on the type of seed, the subspaces will be seeded differently

  • None - All the subspaces will use a random initial seed

  • Int - The integer is used to seed the Tuple space that is used to generate seed values for each of the subspaces. Warning, this does not guarantee unique seeds for all of the subspaces.

  • List - Values used to seed the subspaces. This allows the seeding of multiple composite subspaces (List(42, 54, ...).

PARAMETERS:

seed – An optional list of ints or int to seed the (sub-)spaces.

Sequence

class gymnasium.spaces.Sequence(space: Space[Any]seed: int | np.random.Generator | None = Nonestack: bool = False)

This space represent sets of finite-length sequences.

This space represents the set of tuples of the form \((a_0, \dots, a_n)\) where the \(a_i\) belong to some space that is specified during initialization and the integer \(n\) is not fixed

EXAMPLE

>>> from gymnasium.spaces import Sequence, Box
>>> observation_space = Sequence(Box(0, 1), seed=2)
>>> observation_space.sample()
(array([0.26161215], dtype=float32),)
>>> observation_space = Sequence(Box(0, 1), seed=0)
>>> observation_space.sample()
(array([0.6369617], dtype=float32), array([0.26978672], dtype=float32), array([0.04097353], dtype=float32))

PARAMETERS:

  • space – Elements in the sequences this space represent must belong to this space.

  • seed – Optionally, you can use this argument to seed the RNG that is used to sample from the space.

  • stack – If True then the resulting samples would be stacked.

Sequence.sample(mask: None | tuple[None | np.integer | NDArray[np.integer], Any] = None) → tuple[Any] | Any

Generates a single random sample from this space.

PARAMETERS:

mask –

An optional mask for (optionally) the length of the sequence and (optionally) the values in the sequence. If you specify mask, it is expected to be a tuple of the form (length_mask, sample_mask) where length_mask is

  • None The length will be randomly drawn from a geometric distribution

  • np.ndarray of integers, in which case the length of the sampled sequence is randomly drawn from this array.

  • int for a fixed length sample

The second element of the mask tuple sample mask specifies a mask that is applied when sampling elements from the base space. The mask is applied for each feature space sample.

RETURNS:

A tuple of random length with random samples of elements from the :attr:`feature_space`.

Sequence.seed(seed: int | None = None) → list[int]

Seed the PRNG of this space and the feature space.

Graph

class gymnasium.spaces.Graph(node_space: Box | Discreteedge_space: None | Box | Discreteseed: int | np.random.Generator | None = None)

A space representing graph information as a series of nodes connected with edges according to an adjacency matrix represented as a series of edge_links.

EXAMPLE

>>> from gymnasium.spaces import Graph, Box, Discrete
>>> observation_space = Graph(node_space=Box(low=-100, high=100, shape=(3,)), edge_space=Discrete(3), seed=42)
>>> observation_space.sample()
GraphInstance(nodes=array([[-12.224312 ,  71.71958  ,  39.473606 ],
       [-81.16453  ,  95.12447  ,  52.22794  ],
       [ 57.21286  , -74.37727  ,  -9.922812 ],
       [-25.840395 ,  85.353    ,  28.773024 ],
       [ 64.55232  , -11.317161 , -54.552258 ],
       [ 10.916958 , -87.23655  ,  65.52624  ],
       [ 26.33288  ,  51.61755  , -29.094807 ],
       [ 94.1396   ,  78.62422  ,  55.6767   ],
       [-61.072258 ,  -6.6557994, -91.23925  ],
       [-69.142105 ,  36.60979  ,  48.95243  ]], dtype=float32), edges=array([2, 0, 1, 1, 0, 0, 1, 0]), edge_links=array([[7, 5],
       [6, 9],
       [4, 1],
       [8, 6],
       [7, 0],
       [3, 7],
       [8, 4],
       [8, 8]]))

PARAMETERS:

  • node_space (Union[BoxDiscrete]) – space of the node features.

  • edge_space (Union[NoneBoxDiscrete]) – space of the node features.

  • seed – Optionally, you can use this argument to seed the RNG that is used to sample from the space.

Graph.sample(mask: None | tuple[NDArray[Any] | tuple[Any, ...] | None, NDArray[Any] | tuple[Any, ...] | None] = Nonenum_nodes: int = 10num_edges: int | None = None) → GraphInstance

Generates a single sample graph with num_nodes between 1 and 10 sampled from the Graph.

PARAMETERS:

  • mask – An optional tuple of optional node and edge mask that is only possible with Discrete spaces (Box spaces don’t support sample masks). If no num_edges is provided then the edge_mask is multiplied by the number of edges

  • num_nodes – The number of nodes that will be sampled, the default is 10 nodes

  • num_edges – An optional number of edges, otherwise, a random number between 0 and num_nodes ^ 2

RETURNS:

A :class:`GraphInstance` with attributes `.nodes`, `.edges`, and `.edge_links`.

Graph.seed(seed: int | None = None) → list[int]

Seed the PRNG of this space and possibly the PRNGs of subspaces.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值