In this tutorial, you will learn about imports in Python, get some tips for working with unfamiliar libraries (and the objects they return), and dig into operator overloading.
在本教程中,您将了解 Python 中的 导入,获得一些不熟悉的库(及其返回的对象)的使用技巧,并深入研究 运算符重载。
Imports
So far we've talked about types and functions which are built-in to the language.
But one of the best things about Python (especially if you're a data scientist) is the vast number of high-quality custom libraries that have been written for it.
Some of these libraries are in the "standard library", meaning you can find them anywhere you run Python. Other libraries can be easily added, even if they aren't always shipped with Python.
Either way, we'll access this code with imports.
We'll start our example by importing math
from the standard library.
导入
到目前为止,我们已经讨论了语言内置的类型和函数。
但 Python 最好的事情之一(特别是如果您是一名数据科学家)是为其编写的大量高质量自定义库。
其中一些库位于“标准库”中,这意味着您可以在运行 Python 的任何地方找到它们。 其他库可以轻松添加,即使它们并不总是随 Python 一起提供。
无论哪种方式,我们都将通过 imports 访问此代码。
我们将通过从标准库导入math
来开始我们的示例。
import math
print("It's math! It has type {}".format(type(math)))
It's math! It has type
math
is a module. A module is just a collection of variables (a namespace, if you like) defined by someone else. We can see all the names in math
using the built-in function dir()
.
math
是一个模块。 模块只是由其他人定义的变量的集合(如果您愿意,可以是命名空间)。 我们可以使用内置函数dir()
查看math
中的所有名称。
print(dir(math))
['__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'comb', 'copysign', 'cos', 'cosh', 'degrees', 'dist', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'isqrt', 'lcm', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'nextafter', 'perm', 'pi', 'pow', 'prod', 'radians', 'remainder', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau', 'trunc', 'ulp']
We can access these variables using dot syntax. Some of them refer to simple values, like math.pi
:
我们可以使用点语法访问这些变量。 其中一些引用简单的值,例如math.pi
:
print("pi to 4 significant digits = {:.4}".format(math.pi))
pi to 4 significant digits = 3.142
But most of what we'll find in the module are functions, like math.log
:
但我们在模块中发现的大部分内容都是函数,例如math.log
:
math.log(32, 2)
5.0
Of course, if we don't know what math.log
does, we can call help()
on it:
当然,如果我们不知道 math.log
的作用,我们可以对其调用 help()
:
help(math.log)
Help on built-in function log in module math:
log(...)
log(x, [base=math.e])
Return the logarithm of x to the given base.
If the base not specified, returns the natural logarithm (base e) of x.
We can also call help()
on the module itself. This will give us the combined documentation for all the functions and values in the module (as well as a high-level description of the module). Click the "output" button to see the whole math
help page.
我们还可以在模块本身上调用help()
。 这将为我们提供模块中所有函数和值的组合文档(以及模块的高级描述)。 单击输出
按钮查看整个math
帮助页面。
help(math)
Help on module math:
NAME
math
MODULE REFERENCE
https://docs.python.org/3.10/library/math.html
The following documentation is automatically generated from the Python
source files. It may be incomplete, incorrect or include features that
are considered implementation detail and may vary between Python
implementations. When in doubt, consult the module reference at the
location listed above.
DESCRIPTION
This module provides access to the mathematical functions
defined by the C standard.
FUNCTIONS
acos(x, /)
Return the arc cosine (measured in radians) of x.
The result is between 0 and pi.
acosh(x, /)
Return the inverse hyperbolic cosine of x.
asin(x, /)
Return the arc sine (measured in radians) of x.
The result is between -pi/2 and pi/2.
asinh(x, /)
Return the inverse hyperbolic sine of x.
atan(x, /)
Return the arc tangent (measured in radians) of x.
The result is between -pi/2 and pi/2.
atan2(y, x, /)
Return the arc tangent (measured in radians) of y/x.
Unlike atan(y/x), the signs of both x and y are considered.
atanh(x, /)
Return the inverse hyperbolic tangent of x.
ceil(x, /)
Return the ceiling of x as an Integral.
This is the smallest integer >= x.
comb(n, k, /)
Number of ways to choose k items from n items without repetition and without order.
Evaluates to n! / (k! * (n - k)!) when k <= n and evaluates
to zero when k > n.
Also called the binomial coefficient because it is equivalent
to the coefficient of k-th term in polynomial expansion of the
expression (1 + x)**n.
Raises TypeError if either of the arguments are not integers.
Raises ValueError if either of the arguments are negative.
copysign(x, y, /)
Return a float with the magnitude (absolute value) of x but the sign of y.
On platforms that support signed zeros, copysign(1.0, -0.0)
returns -1.0.
cos(x, /)
Return the cosine of x (measured in radians).
cosh(x, /)
Return the hyperbolic cosine of x.
degrees(x, /)
Convert angle x from radians to degrees.
dist(p, q, /)
Return the Euclidean distance between two points p and q.
The points should be specified as sequences (or iterables) of
coordinates. Both inputs must have the same dimension.
Roughly equivalent to:
sqrt(sum((px - qx) ** 2.0 for px, qx in zip(p, q)))
erf(x, /)
Error function at x.
erfc(x, /)
Complementary error function at x.
exp(x, /)
Return e raised to the power of x.
expm1(x, /)
Return exp(x)-1.
This function avoids the loss of precision involved in the direct evaluation of exp(x)-1 for small x.
fabs(x, /)
Return the absolute value of the float x.
factorial(x, /)
Find x!.
Raise a ValueError if x is negative or non-integral.
floor(x, /)
Return the floor of x as an Integral.
This is the largest integer <= x.
fmod(x, y, /)
Return fmod(x, y), according to platform C.
x % y may differ.
frexp(x, /)
Return the mantissa and exponent of x, as pair (m, e).
m is a float and e is an int, such that x = m * 2.**e.
If x is 0, m and e are both 0. Else 0.5 <= abs(m) < 1.0.
fsum(seq, /)
Return an accurate floating point sum of values in the iterable seq.
Assumes IEEE-754 floating point arithmetic.
gamma(x, /)
Gamma function at x.
gcd(*integers)
Greatest Common Divisor.
hypot(...)
hypot(*coordinates) -> value
Multidimensional Euclidean distance from the origin to a point.
Roughly equivalent to:
sqrt(sum(x**2 for x in coordinates))
For a two dimensional point (x, y), gives the hypotenuse
using the Pythagorean theorem: sqrt(x*x + y*y).
For example, the hypotenuse of a 3/4/5 right triangle is:
>>> hypot(3.0, 4.0)
5.0
isclose(a, b, *, rel_tol=1e-09, abs_tol=0.0)
Determine whether two floating point numbers are close in value.
rel_tol
maximum difference for being considered "close", relative to the
magnitude of the input values
abs_tol
maximum difference for being considered "close", regardless of the
magnitude of the input values
Return True if a is close in value to b, and False otherwise.
For the values to be considered close, the difference between them
must be smaller than at least one of the tolerances.
-inf, inf and NaN behave similarly to the IEEE 754 Standard. That
is, NaN is not close to anything, even itself. inf and -inf are
only close to themselves.
isfinite(x, /)
Return True if x is neither an infinity nor a NaN, and False otherwise.
isinf(x, /)
Return True if x is a positive or negative infinity, and False otherwise.
isnan(x, /)
Return True if x is a NaN (not a number), and False otherwise.
isqrt(n, /)
Return the integer part of the square root of the input.
lcm(*integers)
Least Common Multiple.
ldexp(x, i, /)
Return x * (2**i).
This is essentially the inverse of frexp().
lgamma(x, /)
Natural logarithm of absolute value of Gamma function at x.
log(...)
log(x, [base=math.e])
Return the logarithm of x to the given base.
If the base not specified, returns the natural logarithm (base e) of x.
log10(x, /)
Return the base 10 logarithm of x.
log1p(x, /)
Return the natural logarithm of 1+x (base e).
The result is computed in a way which is accurate for x near zero.
log2(x, /)
Return the base 2 logarithm of x.
modf(x, /)
Return the fractional and integer parts of x.
Both results carry the sign of x and are floats.
nextafter(x, y, /)
Return the next floating-point value after x towards y.
perm(n, k=None, /)
Number of ways to choose k items from n items without repetition and with order.
Evaluates to n! / (n - k)! when k <= n and evaluates
to zero when k > n.
If k is not specified or is None, then k defaults to n
and the function returns n!.
Raises TypeError if either of the arguments are not integers.
Raises ValueError if either of the arguments are negative.
pow(x, y, /)
Return x**y (x to the power of y).
prod(iterable, /, *, start=1)
Calculate the product of all the elements in the input iterable.
The default start value for the product is 1.
When the iterable is empty, return the start value. This function is
intended specifically for use with numeric values and may reject
non-numeric types.
radians(x, /)
Convert angle x from degrees to radians.
remainder(x, y, /)
Difference between x and the closest integer multiple of y.
Return x - n*y where n*y is the closest integer multiple of y.
In the case where x is exactly halfway between two multiples of
y, the nearest even value of n is used. The result is always exact.
sin(x, /)
Return the sine of x (measured in radians).
sinh(x, /)
Return the hyperbolic sine of x.
sqrt(x, /)
Return the square root of x.
tan(x, /)
Return the tangent of x (measured in radians).
tanh(x, /)
Return the hyperbolic tangent of x.
trunc(x, /)
Truncates the Real x to the nearest Integral toward 0.
Uses the __trunc__ magic method.
ulp(x, /)
Return the value of the least significant bit of the float x.
DATA
e = 2.718281828459045
inf = inf
nan = nan
pi = 3.141592653589793
tau = 6.283185307179586
FILE
/home/codespace/.python/current/lib/python3.10/lib-dynload/math.cpython-310-x86_64-linux-gnu.so
Other import syntax
If we know we'll be using functions in math
frequently we can import it under a shorter alias to save some typing (though in this case "math" is already pretty short).
其他导入语法
如果我们知道我们将经常使用math
中的函数,我们可以将其导入到更短的别名下以节省一些输入(尽管在本例中math
已经很短)。
import math as mt
mt.pi
3.141592653589793
You may have seen code that does this with certain popular libraries like Pandas, Numpy, Tensorflow, or Matplotlib. For example, it's a common convention to
import numpy as np
andimport pandas as pd
.您可能已经看到过使用某些流行的库(例如 Pandas、Numpy、Tensorflow 或 Matplotlib)执行此操作的代码。 例如,
import numpy as np
和import pandas as pd
是一种常见的约定。
The as
simply renames the imported module. It's equivalent to doing something like:
as
可以简单的重命名导入的模块。 这相当于做类似的事情:
import math
mt = math
Wouldn't it be great if we could refer to all the variables in the math
module by themselves? i.e. if we could just refer to pi
instead of math.pi
or mt.pi
? Good news: we can do that.
如果我们可以自己引用 math
模块中的所有变量,那不是很好吗? 也就是说,我们是否可以只引用pi
而不是math.pi
或mt.pi
? 好消息:我们可以做到。
from math import *
print(pi, log(32, 2))
3.141592653589793 5.0
import *
makes all the module's variables directly accessible to you (without any dotted prefix).
Bad news: some purists might grumble at you for doing this.
Worse: they kind of have a point.
import *
使您可以直接访问模块的所有变量(没有任何点前缀)。
坏消息:一些纯粹主义者可能会抱怨你这样做。
更糟糕的是:他们有一定道理。
from math import *
from numpy import *
print(pi, log(32, 2))
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[10], line 3
1 from math import *
2 from numpy import *
----> 3 print(pi, log(32, 2))
TypeError: return arrays must be of ArrayType
What has happened? It worked before!
These kinds of "star imports" can occasionally lead to weird, difficult-to-debug situations.
The problem in this case is that the math
and numpy
modules both have functions called log
, but they have different semantics. Because we import from numpy
second, its log
overwrites (or "shadows") the log
variable we imported from math
.
A good compromise is to import only the specific things we'll need from each module:
发生了什么事? 刚才是好的!
这些类型的*号导入
有时会导致奇怪的、难以调试的情况。
这种情况下的问题是math
和numpy
模块都有名为log
的函数,但它们具有不同的语义。 因为我们第二次从numpy
导入,所以它的log
会覆盖(或“隐藏”)我们从math
导入的log
变量。
一个好的折衷方案是仅导入每个模块中我们需要的特定内容:
from math import log, pi
from numpy import asarray
Submodules
We've seen that modules contain variables which can refer to functions or values. Something to be aware of is that they can also have variables referring to other modules.
子模块
我们已经看到模块包含可以引用函数或值的变量。 需要注意的是,它们也可以有引用其他模块的变量。
import numpy
print("numpy.random is a", type(numpy.random))
print("it contains names such as...",
dir(numpy.random)[-15:]
)
numpy.random is a
it contains names such as... ['set_bit_generator', 'set_state', 'shuffle', 'standard_cauchy', 'standard_exponential', 'standard_gamma', 'standard_normal', 'standard_t', 'test', 'triangular', 'uniform', 'vonmises', 'wald', 'weibull', 'zipf']
So if we import numpy
as above, then calling a function in the random
"submodule" will require two dots.
因此,如果我们像上面那样导入numpy
,那么调用random
子模块
中的函数将需要两个点。
# Roll 10 dice
rolls = numpy.random.randint(low=1, high=6, size=10)
rolls
array([2, 2, 2, 4, 1, 3, 4, 5, 1, 1])
Oh the places you'll go, oh the objects you'll see
So after 6 lessons, you're a pro with ints, floats, bools, lists, strings, and dicts (right?).
Even if that were true, it doesn't end there. As you work with various libraries for specialized tasks, you'll find that they define their own types which you'll have to learn to work with. For example, if you work with the graphing library matplotlib
, you'll be coming into contact with objects it defines which represent Subplots, Figures, TickMarks, and Annotations. pandas
functions will give you DataFrames and Series.
In this section, I want to share with you a quick survival guide for working with strange types.
哦,你会去的地方,哦,你会看到的对象
因此,经过 6 节课后,您就成为了整数、浮点数、布尔值、列表、字符串和字典方面的专家(对吧?)。
即使这是真的,事情也不会就此结束。 当您使用各种库来执行专门任务时,您会发现它们定义了自己的类型,您必须学习使用这些类型。 例如,如果您使用图形库matplotlib
,您将接触到它定义的代表子图、图形、刻度标记和注释的对象。 pandas
函数将为您提供数据帧和系列。
在本节中,我想与您分享一个与奇怪类型一起工作的快速生存指南。
Three tools for understanding strange objects
In the cell above, we saw that calling a numpy
function gave us an "array". We've never seen anything like this before (not in this course anyways). But don't panic: we have three familiar builtin functions to help us here.
1: type()
(what is this thing?)
理解奇怪对象的三个工具
在上面的单元格中,我们看到调用numpy
函数给了我们一个数组
。 我们以前从未见过这样的事情(无论如何在本课程中都没有)。 但不要惊慌:我们有三个熟悉的内置函数可以帮助我们。
1: type()
(这是什么东西?)
type(rolls)
numpy.ndarray
2: dir()
(what can I do with it?)
2: dir()
(我能用它做什么?)
print(dir(rolls))
['T', '__abs__', '__add__', '__and__', '__array__', '__array_finalize__', '__array_function__', '__array_interface__', '__array_prepare__', '__array_priority__', '__array_struct__', '__array_ufunc__', '__array_wrap__', '__bool__', '__class__', '__class_getitem__', '__complex__', '__contains__', '__copy__', '__deepcopy__', '__delattr__', '__delitem__', '__dir__', '__divmod__', '__dlpack__', '__dlpack_device__', '__doc__', '__eq__', '__float__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__iand__', '__ifloordiv__', '__ilshift__', '__imatmul__', '__imod__', '__imul__', '__index__', '__init__', '__init_subclass__', '__int__', '__invert__', '__ior__', '__ipow__', '__irshift__', '__isub__', '__iter__', '__itruediv__', '__ixor__', '__le__', '__len__', '__lshift__', '__lt__', '__matmul__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmatmul__', '__rmod__', '__rmul__', '__ror__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__setitem__', '__setstate__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__xor__', 'all', 'any', 'argmax', 'argmin', 'argpartition', 'argsort', 'astype', 'base', 'byteswap', 'choose', 'clip', 'compress', 'conj', 'conjugate', 'copy', 'ctypes', 'cumprod', 'cumsum', 'data', 'diagonal', 'dot', 'dtype', 'dump', 'dumps', 'fill', 'flags', 'flat', 'flatten', 'getfield', 'imag', 'item', 'itemset', 'itemsize', 'max', 'mean', 'min', 'nbytes', 'ndim', 'newbyteorder', 'nonzero', 'partition', 'prod', 'ptp', 'put', 'ravel', 'real', 'repeat', 'reshape', 'resize', 'round', 'searchsorted', 'setfield', 'setflags', 'shape', 'size', 'sort', 'squeeze', 'std', 'strides', 'sum', 'swapaxes', 'take', 'tobytes', 'tofile', 'tolist', 'tostring', 'trace', 'transpose', 'var', 'view']
# If I want the average roll, the "mean" method looks promising...
# 如果我想要平均滚动,`mean`方法看起来很有前途......
rolls.mean()
2.5
# Or maybe I just want to turn the array into a list, in which case I can use "tolist"
# 或者也许我只是想将数组变成列表,在这种情况下我可以使用`tolist`
rolls.tolist()
[2, 2, 2, 4, 1, 3, 4, 5, 1, 1]
3: help()
(tell me more)
3:help()
(告诉我更多)
# That "ravel" attribute sounds interesting. I'm a big classical music fan.
# 这个“ravel”属性听起来很有趣。 我是一名古典音乐迷。
help(rolls.ravel)
Help on built-in function ravel:
ravel(...) method of numpy.ndarray instance
a.ravel([order])
Return a flattened array.
Refer to numpy.ravel
for full documentation.
See Also
--------
numpy.ravel : equivalent function
ndarray.flat : a flat iterator on the array.
# Okay, just tell me everything there is to know about numpy.ndarray
# 好,告诉我有关 numpy.ndarray 的所有信息
# (Click the "output" button to see the novel-length output)
#(点击“输出”按钮可以看到像小说一样的输出)
help(rolls)
Help on ndarray object:
class ndarray(builtins.object)
| ndarray(shape, dtype=float, buffer=None, offset=0,
| strides=None, order=None)
|
| An array object represents a multidimensional, homogeneous array
| of fixed-size items. An associated data-type object describes the
| format of each element in the array (its byte-order, how many bytes it
| occupies in memory, whether it is an integer, a floating point number,
| or something else, etc.)
|
| Arrays should be constructed using array
, zeros
or empty
(refer
| to the See Also section below). The parameters given here refer to
| a low-level method (ndarray(...)
) for instantiating an array.
|
| For more information, refer to the numpy
module and examine the
| methods and attributes of an array.
|
| Parameters
| ----------
| (for the __new__ method; see Notes below)
|
| shape : tuple of ints
| Shape of created array.
| dtype : data-type, optional
| Any object that can be interpreted as a numpy data type.
| buffer : object exposing buffer interface, optional
| Used to fill the array with data.
| offset : int, optional
| Offset of array data in buffer.
| strides : tuple of ints, optional
| Strides of data in memory.
| order : {'C', 'F'}, optional
| Row-major (C-style) or column-major (Fortran-style) order.
|
| Attributes
| ----------
| T : ndarray
| Transpose of the array.
| data : buffer
| The array's elements, in memory.
| dtype : dtype object
| Describes the format of the elements in the array.
| flags : dict
| Dictionary containing information related to memory use, e.g.,
| 'C_CONTIGUOUS', 'OWNDATA', 'WRITEABLE', etc.
| flat : numpy.flatiter object
| Flattened version of the array as an iterator. The iterator
| allows assignments, e.g., `x.flat = 3
(See
ndarray.flat` for
| assignment examples; TODO).
| imag : ndarray
| Imaginary part of the array.
| real : ndarray
| Real part of the array.
| size : int
| Number of elements in the array.
| itemsize : int
| The memory use of each array element in bytes.
| nbytes : int
| The total number of bytes required to store the array data,
| i.e., `itemsize * size
`.
| ndim : int
| The array's number of dimensions.
| shape : tuple of ints
| Shape of the array.
| strides : tuple of ints
| The step-size required to move from one element to the next in
| memory. For example, a contiguous `(3, 4)
` array of type
| `int16
in C-order has strides
(8, 2)
`. This implies that
| to move from element to element in memory requires jumps of 2 bytes.
| To move from row-to-row, one needs to jump 8 bytes at a time
| (`2 * 4
`).
| ctypes : ctypes object
| Class containing properties of the array needed for interaction
| with ctypes.
| base : ndarray
| If the array is a view into another array, that array is its base
| (unless that array is also a view). The base
array is where the
| array data is actually stored.
|
| See Also
| --------
| array : Construct an array.
| zeros : Create an array, each element of which is zero.
| empty : Create an array, but leave its allocated memory unchanged (i.e.,
| it contains "garbage").
| dtype : Create a data-type.
| numpy.typing.NDArray : An ndarray alias :term:generic <generic type>
| w.r.t. its dtype.type <numpy.dtype.type>
.
|
| Notes
| -----
| There are two modes of creating an array using `__new__
`:
|
| 1. If buffer
is None, then only shape
, dtype
, and order
| are used.
| 2. If buffer
is an object exposing the buffer interface, then
| all keywords are interpreted.
|
| No `__init__
` method is needed because the array is fully initialized
| after the `__new__
` method.
|
| Examples
| --------
| These examples illustrate the low-level ndarray
constructor. Refer
| to the See Also
section above for easier ways of constructing an
| ndarray.
|
| First mode, buffer
is None:
|
| >>> np.ndarray(shape=(2,2), dtype=float, order='F')
| array([[0.0e+000, 0.0e+000], # random
| [ nan, 2.5e-323]])
|
| Second mode:
|
| >>> np.ndarray((2,), buffer=np.array([1,2,3]),
| ... offset=np.int_().itemsize,
| ... dtype=int) # offset = 1*itemsize, i.e. skip first element
| array([2, 3])
|
| Methods defined here:
|
| __abs__(self, /)
| abs(self)
|
| __add__(self, value, /)
| Return self+value.
|
| __and__(self, value, /)
| Return self&value.
|
| __array__(...)
| a.__array__([dtype], /)
|
| Returns either a new reference to self if dtype is not given or a new array
| of provided data type if dtype is different from the current dtype of the
| array.
|
| __array_finalize__(...)
| a.__array_finalize__(obj, /)
|
| Present so subclasses can call super. Does nothing.
|
| __array_function__(...)
|
| __array_prepare__(...)
| a.__array_prepare__(array[, context], /)
|
| Returns a view of array
with the same type as self.
|
| __array_ufunc__(...)
|
| __array_wrap__(...)
| a.__array_wrap__(array[, context], /)
|
| Returns a view of array
with the same type as self.
|
| __bool__(self, /)
| True if self else False
|
| __complex__(...)
|
| __contains__(self, key, /)
| Return key in self.
|
| __copy__(...)
| a.__copy__()
|
| Used if :func:copy.copy
is called on an array. Returns a copy of the array.
|
| Equivalent to `a.copy(order='K')
`.
|
| __deepcopy__(...)
| a.__deepcopy__(memo, /)
|
| Used if :func:copy.deepcopy
is called on an array.
|
| __delitem__(self, key, /)
| Delete self[key].
|
| __divmod__(self, value, /)
| Return divmod(self, value).
|
| __dlpack__(...)
| a.__dlpack__(*, stream=None)
|
| DLPack Protocol: Part of the Array API.
|
| __dlpack_device__(...)
| a.__dlpack_device__()
|
| DLPack Protocol: Part of the Array API.
|
| __eq__(self, value, /)
| Return self==value.
|
| __float__(self, /)
| float(self)
|
| __floordiv__(self, value, /)
| Return self//value.
|
| __format__(...)
| Default object formatter.
|
| __ge__(self, value, /)
| Return self>=value.
|
| __getitem__(self, key, /)
| Return self[key].
|
| __gt__(self, value, /)
| Return self>value.
|
| __iadd__(self, value, /)
| Return self+=value.
|
| __iand__(self, value, /)
| Return self&=value.
|
| __ifloordiv__(self, value, /)
| Return self//=value.
|
| __ilshift__(self, value, /)
| Return self<<=value.
|
| __imatmul__(self, value, /)
| Return self@=value.
|
| __imod__(self, value, /)
| Return self%=value.
|
| __imul__(self, value, /)
| Return self*=value.
|
| __index__(self, /)
| Return self converted to an integer, if self is suitable for use as an index into a list.
|
| __int__(self, /)
| int(self)
|
| __invert__(self, /)
| ~self
|
| __ior__(self, value, /)
| Return self|=value.
|
| __ipow__(self, value, /)
| Return self**=value.
|
| __irshift__(self, value, /)
|……
| ----------------------------------------------------------------------
| Data and other attributes defined here:
|
| __hash__ = None
(Of course, you might also prefer to check out the online docs.)
(当然,您可能还喜欢查看在线文档。)
Operator overloading
What's the value of the below expression?
运算符重载
下面的表达式的值是多少?
[3, 4, 1, 2, 2, 1] + 10
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[20], line 1
----> 1 [3, 4, 1, 2, 2, 1] + 10
TypeError: can only concatenate list (not "int") to list
What a silly question. Of course it's an error.
But what about...
多么愚蠢的问题啊。 当然这是一个错误。
但是关于...
rolls + 10
array([12, 12, 12, 14, 11, 13, 14, 15, 11, 11])
We might think that Python strictly polices how pieces of its core syntax behave such as +
, <
, in
, ==
, or square brackets for indexing and slicing. But in fact, it takes a very hands-off approach. When you define a new type, you can choose how addition works for it, or what it means for an object of that type to be equal to something else.
The designers of lists decided that adding them to numbers wasn't allowed. The designers of numpy
arrays went a different way (adding the number to each element of the array).
Here are a few more examples of how numpy
arrays interact unexpectedly with Python operators (or at least differently from lists).
我们可能会认为 Python 严格监管其核心语法片段的行为方式,例如用于索引和切片的+
、<
、in
、==
或方括号。 但事实上,它采取一种无需干涉的方法。 定义新类型时,您可以选择加法的工作方式,或者该类型的对象等于其他对象的含义。
列表的设计者决定不允许将它们添加到数字中。 numpy
数组的设计者采用了不同的方式(将数字添加到数组的每个元素)。
以下是numpy
数组如何与 Python 运算符意外交互的几个示例(或者至少与列表不同)。
# At which indices are the dice less than or equal to 3?
# 哪些索引处的骰子小于或等于 3?
rolls <= 3
array([ True, True, True, False, True, True, False, False, True,
True])
xlist = [[1,2,3],[2,4,6],]
# Create a 2-dimensional array
# 创建一个二维数组
x = numpy.asarray(xlist)
print("xlist = {}\nx =\n{}".format(xlist, x))
xlist = [[1, 2, 3], [2, 4, 6]]
x =
[[1 2 3]
[2 4 6]]
# Get the last element of the second row of our numpy array
# 获取 numpy 数组第二行的最后一个元素
x[1,-1]
6
# Get the last element of the second sublist of our nested list?
# 获取嵌套列表的第二个子列表的最后一个元素?
xlist[1,-1]
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[25], line 2
1 # Get the last element of the second sublist of our nested list?
----> 2 xlist[1,-1]
TypeError: list indices must be integers or slices, not tuple
numpy's ndarray
type is specialized for working with multi-dimensional data, so it defines its own logic for indexing, allowing us to index by a tuple to specify the index at each dimension.
numpy 的 ndarray
类型专门用于处理多维数据,因此它定义了自己的索引逻辑,允许我们通过元组索引来指定每个维度的索引。
When does 1 + 1 not equal 2?
Things can get weirder than this. You may have heard of (or even used) tensorflow, a Python library popularly used for deep learning. It makes extensive use of operator overloading.
什么时候 1 + 1 不等于 2?
事情可能会变得比这更奇怪。 您可能听说过(甚至使用过)tensorflow,这是一个广泛用于深度学习的 Python 库。 它广泛使用运算符重载。
import tensorflow as tf
# Create two constants, each with value 1
a = tf.constant(1)
b = tf.constant(1)
# Add them together to get...
a + b
2024-01-30 06:36:22.442300: I external/local_tsl/tsl/cuda/cudart_stub.cc:31] Could not find cuda drivers on your machine, GPU will not be used.
2024-01-30 06:36:24.689567: E external/local_xla/xla/stream_executor/cuda/cuda_dnn.cc:9261] Unable to register cuDNN factory: Attempting to register factory for plugin cuDNN when one has already been registered
2024-01-30 06:36:24.689687: E external/local_xla/xla/stream_executor/cuda/cuda_fft.cc:607] Unable to register cuFFT factory: Attempting to register factory for plugin cuFFT when one has already been registered
2024-01-30 06:36:25.018022: E external/local_xla/xla/stream_executor/cuda/cuda_blas.cc:1515] Unable to register cuBLAS factory: Attempting to register factory for plugin cuBLAS when one has already been registered
2024-01-30 06:36:25.740675: I external/local_tsl/tsl/cuda/cudart_stub.cc:31] Could not find cuda drivers on your machine, GPU will not be used.
2024-01-30 06:36:25.748642: I tensorflow/core/platform/cpu_feature_guard.cc:182] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations.
To enable the following instructions: AVX2 FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags.
2024-01-30 06:36:28.869582: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Could not find TensorRT
a + b
isn't 2, it is (to quote tensorflow's documentation)...
a + b
不是 2,它是(引用张量流的文档)...
a symbolic handle to one of the outputs of an
Operation
. It does not hold the values of that operation's output, but instead provides a means of computing those values in a TensorFlowtf.Session
.
操作符
输出之一是符号句柄。 它不保存该操作的输出值,而是提供一种在 TensorFlowtf.Session
中计算这些值的方法。
It's important just to be aware of the fact that this sort of thing is possible and that libraries will often use operator overloading in non-obvious or magical-seeming ways.
Understanding how Python's operators work when applied to ints, strings, and lists is no guarantee that you'll be able to immediately understand what they do when applied to a tensorflow Tensor
, or a numpy ndarray
, or a pandas DataFrame
.
Once you've had a little taste of DataFrames, for example, an expression like the one below starts to look appealingly intuitive:
重要的是要意识到这种事情是可能的,并且库经常以不明显或看似神奇的方式使用运算符重载。
了解 Python 运算符在应用于整数、字符串和列表时的工作原理并不能保证您能够立即理解它们在应用于张量流Tensor
、numpy ndarray
或 pandas DataFrame
时的作用 `。
例如,一旦您对 DataFrame 有了一点了解,像下面这样的表达式就会开始看起来非常直观:
# Get the rows with population over 1m in South America
# 获取南美洲人口超过100万的行
df[(df['population'] > 10**6) & (df['continent'] == 'South America')]
But why does it work? The example above features something like 5 different overloaded operators. What's each of those operations doing? It can help to know the answer when things start going wrong.
但为什么它有效呢? 上面的示例具有类似于 5 种不同的重载运算符的功能。 这些操作分别在做什么? 当事情开始出错时,它可以帮助你找到答案。
Curious how it all works?
Have you ever called help()
or dir()
on an object and wondered what the heck all those names with the double-underscores were?
好奇这一切是如何运作的?
您是否曾经对一个对象调用过help()
或dir()
,并且想知道这些带有双下划线的名称到底是什么?
print(dir(list))
['__add__', '__class__', '__class_getitem__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
This turns out to be directly related to operator overloading.
When Python programmers want to define how operators behave on their types, they do so by implementing methods with special names beginning and ending with 2 underscores such as __lt__
, __setattr__
, or __contains__
. Generally, names that follow this double-underscore format have a special meaning to Python.
So, for example, the expression x in [1, 2, 3]
is actually calling the list method __contains__
behind-the-scenes. It's equivalent to (the much uglier) [1, 2, 3].__contains__(x)
.
If you're curious to learn more, you can check out Python's official documentation, which describes many, many more of these special "underscores" methods.
We won't be defining our own types in these lessons (if only there was time!), but I hope you'll get to experience the joys of defining your own wonderful, weird types later down the road.
事实证明,这与运算符重载直接相关。
当 Python 程序员想要定义运算符对其类型的行为时,他们会通过实现具有以 2 个下划线开头和结尾的特殊名称的方法来实现,例如__lt__
、__setattr__
或__contains__
。 通常,遵循这种双下划线格式的名称对 Python 具有特殊含义。
因此,例如,表达式x in [1, 2, 3]
实际上是在幕后调用列表方法__contains__
。 它相当于(更丑陋的)[1, 2, 3].__contains__(x)
。
如果您想了解更多信息,可以查看Python的官方文档,其中描述了很多很多 这些特殊的下划线
方法。
我们不会在这些课程中定义我们自己的类型(除非有时间的话!),但我希望您以后能够体验到定义自己的奇妙而奇怪的类型的乐趣。
Your turn!
Head over to the final coding exercise for one more round of coding questions involving imports, working with unfamiliar objects, and, of course, more gambling.
到你了!
前往 最终编码练习 进行另一轮涉及导入、使用不熟悉的对象的编码问题,当然, 更多赌博。