Các đối tượng là sự trừu tượng hóa dữ liệu của Python. Tất cả dữ liệu trong chương trình Python được biểu diễn bằng đối tượng hoặc bằng quan hệ giữa các đối tượng. [In a sense, and in conformance to Von Neumann’s model of a “stored program computer”, code is also represented by objects. ]
Every object has an identity, a type and a value. An object’s identity never changes once it has been created; you may think of it as the object’s address in memory. The ‘
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule7’ operator compares the identity of two objects; the
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule8 function returns an integer representing its identity
Chi tiết triển khai CPython. For CPython,
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule9 is the memory address where
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass0 is stored
Loại đối tượng xác định các hoạt động mà đối tượng hỗ trợ [e. g. , "nó có độ dài không?"] và cũng xác định các giá trị có thể có cho các đối tượng thuộc loại đó. Hàm
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass1 trả về kiểu của một đối tượng [chính nó là một đối tượng]. Giống như danh tính của nó, loại đối tượng cũng không thể thay đổi. 1
Giá trị của một số đối tượng có thể thay đổi. Các đối tượng có giá trị có thể thay đổi được gọi là có thể thay đổi; . [The value of an immutable container object that contains a reference to a mutable object can change when the latter’s value is changed; however the container is still considered immutable, because the collection of objects it contains cannot be changed. So, immutability is not strictly the same as having an unchangeable value, it is more subtle. ] An object’s mutability is determined by its type; for instance, numbers, strings and tuples are immutable, while dictionaries and lists are mutable
Objects are never explicitly destroyed; however, when they become unreachable they may be garbage-collected. An implementation is allowed to postpone garbage collection or omit it altogether — it is a matter of implementation quality how garbage collection is implemented, as long as no objects are collected that are still reachable
CPython implementation detail. CPython currently uses a reference-counting scheme with [optional] delayed detection of cyclically linked garbage, which collects most objects as soon as they become unreachable, but is not guaranteed to collect garbage containing circular references. See the documentation of the
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass2 module for information on controlling the collection of cyclic garbage. Other implementations act differently and CPython may change. Do not depend on immediate finalization of objects when they become unreachable [so you should always close files explicitly]
Note that the use of the implementation’s tracing or debugging facilities may keep objects alive that would normally be collectable. Also note that catching an exception with a ‘
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass3…
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass4’ statement may keep objects alive
Some objects contain references to “external” resources such as open files or windows. It is understood that these resources are freed when the object is garbage-collected, but since garbage collection is not guaranteed to happen, such objects also provide an explicit way to release the external resource, usually a
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass5 method. Programs are strongly recommended to explicitly close such objects. The ‘
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass3…
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass7’ statement and the ‘
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass8’ statement provide convenient ways to do this
Some objects contain references to other objects; these are called containers. Examples of containers are tuples, lists and dictionaries. The references are part of a container’s value. In most cases, when we talk about the value of a container, we imply the values, not the identities of the contained objects; however, when we talk about the mutability of a container, only the identities of the immediately contained objects are implied. So, if an immutable container [like a tuple] contains a reference to a mutable object, its value changes if that mutable object is changed
Types affect almost all aspects of object behavior. Even the importance of object identity is affected in some sense. for immutable types, operations that compute new values may actually return a reference to any existing object with the same type and value, while for mutable objects this is not allowed. E. g. , after
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass9,
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule30 and
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule31 may or may not refer to the same object with the value one, depending on the implementation, but after
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule32,
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule33 and
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule34 are guaranteed to refer to two different, unique, newly created empty lists. [Note that
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule35 assigns the same object to both
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule33 and
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule34. ]
3. 2. The standard type hierarchy¶
Below is a list of the types that are built into Python. Extension modules [written in C, Java, or other languages, depending on the implementation] can define additional types. Future versions of Python may add types to the type hierarchy [e. g. , rational numbers, efficiently stored arrays of integers, etc. ], although such additions will often be provided via the standard library instead
Some of the type descriptions below contain a paragraph listing ‘special attributes. ’ These are attributes that provide access to the implementation and are not intended for general use. Their definition may change in the future
Không cóThis type has a single value. There is a single object with this value. This object is accessed through the built-in name
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule38. It is used to signify the absence of a value in many situations, e. g. , it is returned from functions that don’t explicitly return anything. Its truth value is falseNotImplemented
This type has a single value. There is a single object with this value. This object is accessed through the built-in name
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule39. Numeric methods and rich comparison methods should return this value if they do not implement the operation for the operands provided. [The interpreter will then try the reflected operation, or some other fallback, depending on the operator. ] It should not be evaluated in a boolean context
See Implementing the arithmetic operations for more details.
Changed in version 3. 9. Evaluating
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule39 in a boolean context is deprecated. While it currently evaluates as true, it will emit a
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule41. It will raise a
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule42 in a future version of Python. Ellipsis
This type has a single value. There is a single object with this value. This object is accessed through the literal
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule43 or the built-in name
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule44. Its truth value is true
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule45
These are created by numeric literals and returned as results by arithmetic operators and arithmetic built-in functions. Numeric objects are immutable; once created their value never changes. Python numbers are of course strongly related to mathematical numbers, but subject to the limitations of numerical representation in computers
The string representations of the numeric classes, computed by
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule46 and
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule47, have the following properties
They are valid numeric literals which, when passed to their class constructor, produce an object having the value of the original numeric
The representation is in base 10, when possible
Leading zeros, possibly excepting a single zero before a decimal point, are not shown
Trailing zeros, possibly excepting a single zero after a decimal point, are not shown
A sign is shown only when the number is negative
Python distinguishes between integers, floating point numbers, and complex numbers
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule48
These represent elements from the mathematical set of integers [positive and negative]
There are two types of integers
Integers [import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule49]
These represent numbers in an unlimited range, subject to available [virtual] memory only. For the purpose of shift and mask operations, a binary representation is assumed, and negative numbers are represented in a variant of 2’s complement which gives the illusion of an infinite string of sign bits extending to the left
Booleans [class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass30]
Chúng đại diện cho các giá trị thật Sai và Đúng. The two objects representing the values
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass31 and
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass32 are the only Boolean objects. The Boolean type is a subtype of the integer type, and Boolean values behave like the values 0 and 1, respectively, in almost all contexts, the exception being that when converted to a string, the strings
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass33 or
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass34 are returned, respectively
The rules for integer representation are intended to give the most meaningful interpretation of shift and mask operations involving negative integers
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass35 [
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass36]
Chúng đại diện cho các số dấu phẩy động chính xác kép ở cấp độ máy. You are at the mercy of the underlying machine architecture [and C or Java implementation] for the accepted range and handling of overflow. Python không hỗ trợ các số dấu phẩy động có độ chính xác đơn;
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass37 [
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass38]
Chúng biểu thị các số phức dưới dạng một cặp số dấu phẩy động chính xác kép ở cấp độ máy. Các cảnh báo tương tự áp dụng cho các số dấu phẩy động. Phần thực và phần ảo của một số phức
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass39 có thể được truy xuất thông qua các thuộc tính chỉ đọc
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass30 và
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass31trình tự
Chúng đại diện cho các tập hợp có thứ tự hữu hạn được lập chỉ mục bởi các số không âm. Hàm tích hợp
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass32 trả về số lượng phần tử của một chuỗi. Khi độ dài của một dãy là n, bộ chỉ số chứa các số 0, 1, …, n-1. Mục i của dãy a được chọn bởi
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass33
Trình tự cũng hỗ trợ cắt.
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass34 chọn tất cả các mục có chỉ số k sao cho i
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass35 k
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass36 j. Khi được sử dụng như một biểu thức, một lát cắt là một chuỗi cùng loại. Điều này ngụ ý rằng bộ chỉ mục được đánh số lại để nó bắt đầu từ 0
Một số trình tự cũng hỗ trợ “cắt lát mở rộng” với tham số “bước” thứ ba.
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass37 chọn tất cả các mục của a có chỉ số x trong đó
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass38, n
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass39
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass30 và i
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass35 x
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass36 j
Các trình tự được phân biệt theo khả năng biến đổi của chúng
Trình tự bất biếnMột đối tượng thuộc loại chuỗi bất biến không thể thay đổi sau khi được tạo. [Nếu đối tượng chứa các tham chiếu đến các đối tượng khác, các đối tượng khác này có thể thay đổi được và có thể bị thay đổi; tuy nhiên, tập hợp các đối tượng được tham chiếu trực tiếp bởi một đối tượng bất biến không thể thay đổi. ]
The following types are immutable sequences
StringsA string is a sequence of values that represent Unicode code points. All the code points in the range
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass33 can be represented in a string. Python doesn’t have a char type; instead, every code point in the string is represented as a string object with length
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass34. The built-in function
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass35 converts a code point from its string form to an integer in the range
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass36;
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass37 converts an integer in the range
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass36 to the corresponding length
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass34 string object.
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass30 can be used to convert a
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass31 to
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass32 using the given text encoding, and
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass33 can be used to achieve the opposite. Tuples
The items of a tuple are arbitrary Python objects. Tuples of two or more items are formed by comma-separated lists of expressions. A tuple of one item [a ‘singleton’] can be formed by affixing a comma to an expression [an expression by itself does not create a tuple, since parentheses must be usable for grouping of expressions]. An empty tuple can be formed by an empty pair of parentheses
BytesA bytes object is an immutable array. The items are 8-bit bytes, represented by integers in the range 0