Hướng dẫn is python a static typed language? - python có phải là ngôn ngữ nhập tĩnh không?

There are some important issues that I think all of the existing answers have missed.


Weak typing means allowing access to the underlying representation. In C, I can create a pointer to characters, then tell the compiler I want to use it as a pointer to integers:

char sz[] = "abcdefg";
int *i = (int *)sz;

On a little-endian platform with 32-bit integers, this makes i into an array of the numbers 0x64636261 and 0x00676665. In fact, you can even cast pointers themselves to integers (of the appropriate size):

intptr_t i = (intptr_t)&sz;

And of course this means I can overwrite memory anywhere in the system.*

char *spam = (char *)0x12345678
spam[0] = 0;

* Of course modern OS's use virtual memory and page protection so I can only overwrite my own process's memory, but there's nothing about C itself that offers such protection, as anyone who ever coded on, say, Classic Mac OS or Win16 can tell you.

Traditional Lisp allowed similar kinds of hackery; on some platforms, double-word floats and cons cells were the same type, and you could just pass one to a function expecting the other and it would "work".

Most languages today aren't quite as weak as C and Lisp were, but many of them are still somewhat leaky. For example, any OO language that has an unchecked "downcast",* that's a type leak: you're essentially telling the compiler "I know I didn't give you enough information to know this is safe, but I'm pretty sure it is," when the whole point of a type system is that the compiler always has enough information to know what's safe.

* A checked downcast doesn't make the language's type system any weaker just because it moves the check to runtime. If it did, then subtype polymorphism (aka virtual or fully-dynamic function calls) would be the same violation of the type system, and I don't think anyone wants to say that.

Very few "scripting" languages are weak in this sense. Even in Perl or Tcl, you can't take a string and just interpret its bytes as an integer.* But it's worth noting that in CPython (and similarly for many other interpreters for many languages), if you're really persistent, you can use ctypes to load up libpython, cast an object's id to a POINTER(Py_Object), and force the type system to leak. Whether this makes the type system weak or not depends on your use cases—if you're trying to implement an in-language restricted execution sandbox to ensure security, you do have to deal with these kinds of escapes…

* You can use a function like

intptr_t i = (intptr_t)&sz;
0 to read the bytes and build a new int out of "how C would represent these bytes", but that's obviously not leaky; even Haskell allows that.


Meanwhile, implicit conversion is really a different thing from a weak or leaky type system.

Every language, even Haskell, has functions to, say, convert an integer to a string or a float. But some languages will do some of those conversions for you automatically—e.g., in C, if you call a function that wants a

intptr_t i = (intptr_t)&sz;
1, and you pass it in
intptr_t i = (intptr_t)&sz;
2, it gets converted for you. This can definitely lead to bugs with, e.g., unexpected overflows, but they're not the same kinds of bugs you get from a weak type system. And C isn't really being any weaker here; you can add an int and a float in Haskell, or even concatenate a float to a string, you just have to do it more explicitly.

And with dynamic languages, this is pretty murky. There's no such thing as "a function that wants a float" in Python or Perl. But there are overloaded functions that do different things with different types, and there's a strong intuitive sense that, e.g., adding a string to something else is "a function that wants a string". In that sense, Perl, Tcl, and JavaScript appear to do a lot of implicit conversions (

intptr_t i = (intptr_t)&sz;
3 gives you
intptr_t i = (intptr_t)&sz;
4), while Python does a lot fewer (
intptr_t i = (intptr_t)&sz;
3 raises an exception, but
intptr_t i = (intptr_t)&sz;
6 does give you
intptr_t i = (intptr_t)&sz;
7*). It's just hard to put that sense into formal terms—why shouldn't there be a
intptr_t i = (intptr_t)&sz;
8 that takes a string and an int, when there are obviously other functions, like indexing, that do?

* Actually, in modern Python, that can be explained in terms of OO subtyping, since

intptr_t i = (intptr_t)&sz;
9 is true. I don't think there's any sense in which
char *spam = (char *)0x12345678
spam[0] = 0;
0 is an instance of the string type in Perl or JavaScript… although in Tcl, it actually is, since everything is an instance of string.


Finally, there's another, completely orthogonal, definition of "strong" vs. "weak" typing, where "strong" means powerful/flexible/expressive.

For example, Haskell lets you define a type that's a number, a string, a list of this type, or a map from strings to this type, which is a perfectly way to represent anything that can be decoded from JSON. There's no way to define such a type in Java. But at least Java has parametric (generic) types, so you can write a function that takes a List of T and know that the elements are of type T; other languages, like early Java, forced you to use a List of Object and downcast. But at least Java lets you create new types with their own methods; C only lets you create structures. And BCPL didn't even have that. And so on down to assembly, where the only types are different bit lengths.

Vì vậy, theo nghĩa đó, hệ thống loại của Haskell mạnh hơn Java hiện đại, mạnh hơn Java trước đó, mạnh hơn C, mạnh hơn BCPL.

Vì vậy, Python phù hợp với quang phổ đó ở đâu? Đó là một chút khó khăn. Trong nhiều trường hợp, gõ vịt cho phép bạn mô phỏng mọi thứ bạn có thể làm trong Haskell và thậm chí một số thứ bạn không thể; Chắc chắn, các lỗi bị bắt trong thời gian chạy thay vì thời gian biên dịch, nhưng chúng vẫn bị bắt. Tuy nhiên, có những trường hợp gõ vịt không đủ. Ví dụ: trong Haskell, bạn có thể nói rằng một danh sách số trống của INTS là danh sách các INT, vì vậy bạn có thể quyết định rằng việc giảm

intptr_t i = (intptr_t)&sz;
8 trong danh sách đó sẽ trả về 0*; Trong Python, một danh sách trống là một danh sách trống; Không có thông tin loại nào để giúp bạn quyết định giảm
intptr_t i = (intptr_t)&sz;
8 so với nó nên làm.

* Trên thực tế, Haskell không cho phép bạn làm điều này; Nếu bạn gọi hàm giảm không lấy giá trị bắt đầu trong danh sách trống, bạn sẽ gặp lỗi. Nhưng hệ thống loại của nó đủ mạnh để bạn có thể thực hiện công việc này và Python thì không.

Có phải Python trở thành gõ tĩnh?

Có hai loại ngôn ngữ lập trình: các ngôn ngữ được đánh máy và gõ linh hoạt. Python là một ngôn ngữ được đánh máy động. Bạn không phải chỉ định rõ ràng kiểu dữ liệu của các biến. Điều tương tự cũng đúng với các chức năng: bạn không phải chỉ định loại đối số hoặc loại trả về của hàm.Python is a dynamically typed language. You don't have to explicitly specify the data type of variables. The same is true for functions: You don't have to specify the type of arguments or the function's return type.

Tại sao Python được gõ động?

Python không có bất kỳ vấn đề nào ngay cả khi chúng tôi không khai báo loại biến.Nó nói rằng loại biến trong thời gian chạy của chương trình.Python cũng quan tâm đến việc quản lý bộ nhớ rất quan trọng trong lập trình.Vì vậy, Python là một ngôn ngữ được đánh máy động.

Ngôn ngữ được đánh máy tĩnh là gì?

Một ngôn ngữ được gõ tĩnh là ngôn ngữ (như Java, C hoặc C ++) trong đó các loại biến được biết đến tại thời điểm biên dịch.Trong hầu hết các ngôn ngữ này, các loại phải được chỉ định rõ ràng bởi lập trình viên;Trong các trường hợp khác (chẳng hạn như OCAML), kiểu suy luận cho phép lập trình viên không chỉ ra các loại biến của chúng.a language (such as Java, C, or C++) where variable types are known at compile time. In most of these languages, types must be expressly indicated by the programmer; in other cases (such as OCaml), type inference allows the programmer to not indicate their variable types.

Các biến python là tĩnh hay động?

Python là một ngôn ngữ được đánh máy động.00:12 Trình thông dịch Python chỉ kiểm tra loại khi mã chạy.Khi bạn thực hiện một dòng mã, như bạn sẽ thấy trong một ví dụ tiếp theo, đó là khi kiểm tra loại xảy ra.00:23 Và cũng, loại biến được phép thay đổi trong suốt vòng đời của nó.dynamically typed language. 00:12 The Python interpreter does type checking only when the code runs. As you execute a line of code, as you'll see in an example next, that's when the type checking occurs. 00:23 And also, the type of a variable is allowed to change over its lifetime.