In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-11 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
What is the introduction to Python tutorial suitable for Java developers? in view of this problem, this article introduces the corresponding analysis and solutions in detail, hoping to help more partners who want to solve this problem to find a more simple and easy way.
From a philosophical point of view, Python is almost the opposite of Java. Instead of static types and rigid structures, it uses a loose sandboxie, in which you are free to do whatever you want. Maybe Python is about what you can do, and Java is about what you can do.
However, both languages draw a lot of inspiration from the C language. They are all imperative languages, with blocks, loops, methods, assignments, and infix arithmetic (infix math). Both make heavy use of classes, objects, inheritance, and polymorphism. The abnormal functions of both are quite excellent. Both can automatically manage memory. They are all compiled into bytecode that can be run on some virtual machine, although Python is compiled transparently. Python even draws some nourishment from Java: for example, the logging and unittest modules of the basic library are inspired by log4j and JUnit, respectively.
Given the overlap of the above technologies, I think Java developers should feel at home when using Python. So let me give you some simple Python introductions. I will be able to tell you what makes Python different from Java and why I find these differences attractive. At the very least, you may find some interesting ideas that bring you back to the Java ecosystem.
(if you want a Python tutorial, Python documentation is a good choice, and it is written from the perspective of Python 3, the use of Python 2 is still very common, it has some grammatical differences with Python 3
Grammar
Let's figure out the grammar first. Here's how to get started with hello world:
Print ("Hello, world!")
Well, it's not very enlightening. All right, let's take a look at another function to see how to find the 10 most common words in a file. I skillfully use the Counter type of the standard library here, but it is so easy to use.
From collections import Counter def count_words (path): words = Counter () with open (path) as f: for line in f: for word in line.strip () .split (): words [word] + = 1 for word, count in words.most_common (10): print (f "{word} x {count}")
Python is separated by spaces. People often have strong opinions about it. When I saw it for the first time, I even thought it was heresy. Now, more than a decade later, it seems so natural that it is very difficult for me to return to the curly braces. If you run away from it, I even doubt that I can convince you, but I advise you to ignore it at least for a while; in fact, it does not cause any serious problems, but eliminates a lot of interference. In addition, Python developers never have to argue about {where to put it.
Apart from the aesthetic differences, other aspects should look familiar. We have some numbers, some assignments, and some method calls. The import statement works somewhat differently, but it has the same general meaning of "make these contents available." Python's for loop is very similar to Java's for-each loop, except for the lack of punctuation. The function itself is separated by def instead of type, but it works exactly the way you want it to: you can call it with arguments and return a value (although some functions do not return values).
Only two things are very unusual. One is the with block, which is very similar to Java 7's "try-with-resources"-it ensures that the file is closed at the end of the block, even if an exception is thrown. The other is f "…" Syntax, which is a fairly new feature that allows expressions to be inserted directly into strings.
okay! You have read some Python content. At the very least, it is not a language from a completely different planet.
Dynamic type
It may be obvious to look at this example, but there is not much type declaration in the Python code. Not on the variable declaration, not on the parameter or return type, nor on the object. Any value can be of any type at any time. I haven't shown a class definition yet, so it's just a simple definition.
Class Point: def _ init__ (self, x, y): self.x = x self.y = y def magnitude (self): return (self.x * * 2 + self.y * * 2) * * 0.5 point = Point (3,4) print (point.x) # 3 print (point.magnitude ()) # 5.0
Although x and y are not defined as attributes, they exist because they are created in the constructor. No one forces me to pass an integer parameter. I can also pass decimals and fractions.
If you've only used static languages before, this may seem like a mess. The type is warm, lazy and satisfying. They guarantee (well, maybe not) that the code actually works (though some people disagree). But how can you rely on code when you don't know what the right type is?
But wait-Java doesn't have such a guarantee! After all, any object could be null, right? In fact, there is almost never an object of the right type.
You might think of dynamic typing as a complete abandonment of the null problem. If we have to deal with it, we might as well embrace it and let it work for us-by delaying everything until runtime. Type errors become normal logic errors, and you can handle them in the same way.
(for the opposite approach, see Rust, which has no null values-or exceptions, I'd rather write Python, but I appreciate that Rust's type system doesn't always lie to me.)
In my magnitude method, it doesn't matter whether self.x is int or float or any other type. It only needs to support the * operator and return the content that supports the + operator. (Python supports operator overloading, so this could be anything.) The same applies to normal method calls: any type is acceptable, as long as it actually works.
This means that Python doesn't need generics; everything works according to generics. No interface is needed; everything is already polymorphic. No downward transition (downcasts), no upward transition (upcasts), no escape hatch (escape hatches) in the type system. When they work well with any Iterable, the runtime API does not need List.
Many common patterns have become easier. You can create wrapper objects and proxies without changing the consumption code. You can use composition instead of inheritance to extend third-party types without having to do anything special to preserve polymorphism. Flexible API does not need to copy every class as an interface; everything is already an implicit interface.
Dynamic type philosophy
Using static types, no matter who writes some code to select them, the compiler checks to see if they work properly. Using dynamic types, no matter who uses some code to select these types, the runtime will try. This is where opposing philosophies work: the type system focuses on what you can do, not what you might do.
This use of dynamic types is sometimes called "duck typing", based on the idea: "if it walks like a duck and barks like a duck, then it is a duck." In other words, if you want something that croaks like a duck, you don't have to force your code to accept a duck object. Instead, you can accept anything given to you and make it quack. If it can achieve your goal, then it will be as good as a duck. (otherwise, if it doesn't work out as you want, it will throw an AttributeError error, but it's no big deal.)
Also note that Python is strongly typed. The word is a bit vague, and it usually means that the value of a variable remains the same at run time. A typical example is that Python does not let you assign a string to a variable of a numeric type, while weakly typed languages such as JavaScript can silently convert one type to another, where the priority rule is used, which is different from what you expect.
Unlike most dynamic languages, Python can catch error messages before it is run. For example, reading a nonexistent variable generates an exception, including an error when reading a nonexistent key from a dictionary object such as Map. In JavaScript, Lua, and similar languages, the above two cases return the null value. (Java also returns a null value). If you want to return the default value if the value does not exist, the dictionary class provides a more explicit method call.
This is definitely a tradeoff, and whether it is worth it depends on different projects and people. For me, it is at least very suitable for designing a more reliable system, thinking that I can see how it actually works. But statically typed languages expect a pre-design. Static types are difficult to try a variety of ideas, and even harder to play.
You do have less static checking guarantees, but in my experience, most type errors can be caught correctly. Because the only thing I did when I finished writing the code was to try to run it! Any other errors should be caught by your tests-tests should be available in all languages, and writing tests in the python language is relatively easy.
A mixed example
Python and Java are both imperative and object-oriented: they work by executing instructions, and they shape everything into objects.
In the recent release, Java has added some functional language features, which I think is a good thing. Python also has functional language features, but it is implemented in a different way. It provides some built-in functions such as map and reduce, but it is not based on the idea of concatenating many small functions.
Instead, Python mixes something else. I don't know the common name of the method used by Python. I think it divides the idea of "function chain" into two: acting on the sequence and making the function itself more useful.
Sequence
Sequence and iteration play an important role in Python. Sequence is the most basic data structure, and it is very valuable as a tool on it. I think Python's implementation of functional programming is as follows: Python first makes it easy to manipulate sequences using imperative code, rather than making it easy to combine many small functions and then apply them to sequences.
Going back to the beginning of this article, I wrote this line of code:
For word, count in words.most_common (10):
The for loop is familiar to us, but this line of code iterates over two variables at a time. What actually happens is that each element in the list most_common returns a tuple, which is a sequential set of values. What really happens is that tuples can be unpackaged by assigning them to tuple variable names. Tuples are typically used to return multiple values in Python, but they can occasionally be used for special structures. In Java, you need a complete class and a few lines of code that assign values.
Anything that can be iterated can also be unpacked. Unpacking supports arbitrary nesting, so a, (b _ (m) c) =... Unpack it the way it looks. For sequences of unknown length, a * leftovers element can appear anywhere and will get as many elements as needed. Maybe you will really like LISP?
Values = [5,7,9] head, * tail = values print (head) # 5 print (tail) # (7,9)
Python also has a syntax for creating lists through simple expressions-so-called "list parsing"-which is more common than functional methods such as map. There is a similar syntax for creating groups and collections. The whole loop can be reduced to a single expression that highlights only the parts you are really interested in.
Values = [3,4,5] values2 = [val * 2 for val in values if val! = 4] print (values2) # [6,10]
The standard library also includes many interesting iterations, combiners, and usage in the itertools module.
* Python has a generator for generating delay sequences for command-line code. The function that contains the yield keyword does not execute immediately when called; instead, it returns a generator object. When the generator iteration ends, the function runs until it encounters a yield, at which point it pauses; the generated value becomes the next iteration value.
Def odd_numbers (): n = 1 while True: yield n n + = 2 for x in odd_numbers (): print (x) if x > 4: break # 1 # 3 # 5
Because generators are delayed, they can generate sequences or break halfway. They can produce a large number of large objects without consuming a lot of memory by keeping them all alive. They can also be used as a general alternative to the "chained" functional programming style. Instead of combining map and filter, you can write familiar command-line code.
# This is the pathlib.Path API from the standard library def iter_child_filenames (dirpath): for child in dirpath.iterdir (): if child.is_file (): yield child.name
To represent a completely arbitrary lazy iterator in Java, you need to write an Iterator that tracks its state manually. All of this can be tricky except in the simplest case. Python also has an iteration interface, so you can still use this approach, but the generator is so easy to use that most custom iterations are written with them.
And because generators can pause themselves, they are useful in other contexts. By calling the generator manually (rather than iterating all at once with just one for loop), you can run a function over a period of time, stop it at some point, and run other code before restoring the function. Python takes full advantage of this to add support for asynchronous Imax O (a non-blocking network that does not use threads), although it now has dedicated async and await syntax.
Function
At first glance, Python's functions look familiar. You can call them with parameters. The delivery style is exactly the same as Java-Python has neither reference nor implicit copy. Python even has "docstrings", similar to Javadoc comments, but it is built-in syntax and is visible at run time.
Def foo (a, b, c): "" Print out the arguments. Not a very useful function, really. "" Print ("I got", a, b, c) foo (1,2,3) # I got 1 2 3
Java has args... A variable function of syntax; Python can achieve similar functionality using * args. (the * leftovers syntax for unpacking is inspired by functional syntax.) But Python also has some tricks. Any parameter can have a default value, making it optional. Any parameter can also be given by name-I demonstrated this earlier using Point (x = 3 and y = 4). When calling any function, you can use the * args syntax, which passes a sequence as if it were a separate parameter, and there is an equivalent * * kwargs that accepts or passes the named parameter as a dict. A parameter can be used as a "keyword-only only", so it must be passed by name, which is good for optional Boolean values.
Python certainly doesn't have function overloads, but most of the functions you implement with it can be replaced by duck typing and optional arguments.
This is one of the major functions of Python*** at this stage. As with dynamic types, you can transparently replace objects through wrappers or proxies, and * args and * kwargs allow any function to be wrapped transparently.
Def log_calls (old_function): def new_function (* args, * * kwargs): print ("i'm being called!", args, kwargs) return old_function (* args, * * kwargs) return new_function @ log_calls def foo (a, b, cym3): print (f "a = {a}, b = {b}, c = {c}") foo (1, bx2) # i'm being called! (1 ) {'baked: 2} # a = 1, b = 2, c = 3
It's a little hard to understand. I'm sorry. Don't worry about exactly how it works; the point is that foo is replaced by a new_function, which forwards all the parameters to foo. Neither foo nor the caller needs to know which things are different.
I can't underestimate how powerful it is. It can be used for recording, debugging, managing resources, caching, access control, authentication, etc. It works well with other metaprogramming features, just as it allows you to break down the structure, not just the code.
Object and dynamic runtime
The dynamic runtime is something that drives the core of the language behind it-it can be executed at run time. Languages like C or C++ will never have a dynamic runtime; the structure of their source code is "baked" into compiled output, and there is no obvious way to change its behavior later. On the other hand, Java does have a dynamic runtime! It even comes with a whole package dedicated to reflection.
Python certainly has reflexes. Many simple functions are built through reflection to check or modify the properties of objects online, which is useful for debugging and occasional spoofing.
But Python goes a little deeper. Because everything is done at run time, Python exposes many extension points to define its semantics. You can't change the syntax, the code still looks like Python, but you can break down the structure-which is very difficult to do in a more rigid language.
To take an extreme example, take a look at pytest, which cleverly handles Python's assert declaration. Usually, when assert x = = 1 is false, it will simply throw an AssertionError exception, so you don't know what the error is or where it went wrong. This is why Python's built-in unit test modules-like JUnit and many other testing tools-provide many specialized tool functions, such as assertEquals. Unfortunately, these utility functions make the test more complex and difficult to read at first sight. But in pytest, assert x = = 1 is useful. If it fails, pytest will tell you that x is... Or where there are differences between the two lists, or which elements of the two collections are different, or something else. All of this occurs automatically based on comparison completion and the type of Operand.
How does pytest work? You really don't want to know. You don't need to know how to write tests in pytest-it makes people happy.
This is the real advantage of dynamic runtime. For your part, you may not use these features. But you can reap huge benefits from these libraries, and you don't need to care how they work when you use them. Even Python itself implements a lot of additional features using its own extension points-without changing the syntax or interpreter.
Object
Property access (which is generally translated as a feature in C #) is a simple example that I like to give. In Java, a Point class might choose to use the getX () and setX () methods instead of a simple, straightforward x attribute. The reason is that if you need to change the read or write of x, you don't need to break the interface. In Python, you don't need to worry about the above, because you can explain property access if necessary.
Class Point: def _ init__ (self, x, y): self._x = x self._y = y @ property def x (self): return self._x #... Same for y... Point = Point (3,4) print (point.x) # 3
The interesting @ property syntax is an embellishment that looks like a Java annotation, but it can modify a function or class more directly. This is completely transparent calling code-- no different from reading other properties-- but the object can intervene or handle it according to its own needs. Unlike Java, property access is part of the class API and can be defined freely. Note that this example makes x read-only because I did not specify a write method! The syntax of the writable attribute is a bit funny, regardless of how it works for the time being. But you can specify that only odd numbers can be assigned to point.x.)
This feature also exists in other static languages, such as caching, so it's not a big deal. The really interesting part about Python is that attributes are nothing special. It is a normal built-in type, a pure and dissatisfied one-screen Python program. How it works is that the Python class can customize its property access, both generic and by attribute. Wrapper, proxy, and composition are easy to implement: you can forward all access calls to the underlying object without knowing what methods it has.
The same hook properties can be used to lazily load properties or automatically hold weakly referenced properties-- this is completely transparent to the calling code and can be achieved through pure Python.
You may have noticed that my code does not use public or private modifiers. In fact, this concept does not exist in Python. By convention, start with an underscore to indicate "private"-or, more likely, "not intended to be part of a stable public API." But this has no linguistic meaning, and Phthon itself does not prevent detection or modification of such properties (or, in the case of methods, calls). Similarly, there is no final, static, or const.
It's the same principle: the core Python usually doesn't prevent you from doing anything. It can be very useful if you need it. I have patched the BUG of third-party libraries by calling or rewriting or even redefining private methods at startup. In this way, I don't have to redo a local branch of the project, which can save me a lot of trouble. And as soon as you officially fix BUG, you can easily delete your own patch code.
Similarly, you can easily write test code that depends on external state-such as the current time. If refactoring is not feasible, you can replace time.time () with a mock function when testing. Library functions are just properties of module modules (like Java packages), and Python modules are objects, like other objects, so they can be detected or modified in the same way.
Class
The class of Java is supported by the Class object, but the two are not completely interchangeable. For example, the Class object of the Foo class is Foo.class. I don't think Foo can be used by itself, because it names a type, and Java has some subtle differences when dealing with types and values.
In Python, a class is an object, an instance of a type (it is an object itself, an instance of itself, which is interesting to remember.) Classes can be used as other values: as parameters, to save a larger data structure, to check, to manipulate. Sometimes it is especially useful to use a class as a key to a dictionary. And because classes are instantiated, you can simply call them-- Python doesn't have the new keyword-- and in many cases new and simple function calls are interchangeable. As a result, some common patterns, such as the factory model, are so simple that they are almost unnecessary.
# wait, is Vehicle a class or a factory function? Who cares! # even if it is exchanged between classes or factory functions, it will not break this code. Car = Vehicle (wheels=4, doors=4)
Recently, I have put functions and even regular code at the top level several times, not in any class. There will be no problem with this, but the meaning is a bit subtle. Even class and def in Python are regular code that is executed at run time. Python files are executed from top to bottom, and class and def are not special. They just have special syntax for creating specific types of objects: classes and functions.
Here's the really cool part. Classes are objects, and their type is type, so you can subclass and change its operation. You can then generate an instance of your subclass.
If you think about it, it will feel a little strange. But when you think about it, you benefit from not knowing how it works. For example, Python does not have an enum block, but it does have enum module:
Class Animal (Enum): cat = 0 dog = 1 mouse = 2 snake = 3 print (Animal.cat) # print (Animal.cat.value) # 0 print (Animal (2)) # print (Animal ['dog']) #
The class statement creates an object, which means that it calls the constructor somewhere, and you can override the constructor to change the way the class is constructed. Here Enum creates a fixed set of instances rather than class attributes. All of this is done using the regular Python syntax of normal Python code.
The entity library is also constructed based on this idea. Do you hate doing things like self.foo = foo monotonously in constructors? Then manually define equality comparisons, hashes, and clone and develop readable lists? Java requires compiler support, which may come from Amber projects. Python is very flexible, so there are attrs libraries in the community that solve this problem.
Import attr @ attr.s class Point: X = attr.ib () y = attr.ib () p = Point (3,4) Q = Point (x # True, y = 4) p = = Q # True, which it wouldn't have been before! Print (p) # Point (Xerox 3, YB4)
Or use SQLAlchemy, a powerful Python database encapsulation library. It contains an ORM inspired by Hibernate, but instead of defining the table structure in the configuration file or other lengthy annotations, you can write database mapping code directly in the class:
Class Order (Table): id = Column (Integer, primary_key=True) order_number = Column (Integer, index=True) status = Column (Enum ('pending',' complete'), default='pending').
Its basic idea is similar to Enum, but SQLAlchemy also uses the same hooks as property, so naturally, you can modify the field values.
Order.order_number = 5 session.commit ()
* the class itself can be created at run time. This has some advantages, but the entire module created by thriftpy is full of classes based on the Thrift definition file. In Java, you need code generation, which adds a whole new compilation step, resulting in out-of-sync.
All of these examples rely on Python's existing syntax, but also absorb new meanings in it. There's nothing it can do that you can't do in Java or other languages. But it removes structural repetition-something that makes coding easier to write, easier to read, and produces less bug.
Conclusion
Python has many of the same basic concepts as Java, but deals with it in a very different direction, adding some completely new ideas. Java focuses on stability and reliability, while Python focuses on expressiveness and flexibility. It's a completely different way of thinking about imperative programming.
I have reason to believe that Python will let you replace Java in what Java is good at. Python may not win speed races, such as (Pypy, a just-in-time compiled Python). Java has native support for threads, and the Python world mostly avoids these issues. Software that is large and complex and has many dead ends prefers the reasonableness checks provided by static types (such as mypy, an Python static type checker).
Maybe some areas that Java is not good at happen to be Python's strengths. For example, a large number of software does not require high performance and does not need to be executed in parallel, we only need to consider the specific implementation of the business. I find it easy and fast to start a project with Python. Without a separate compilation process, coding and then running is very fast. The code is short, which means it is easier to understand. It seems easier to try different architectural approaches. And sometimes it's so interesting to try some stupid ideas, just like using libraries to implement goto functions.
I hope you can try Python. I've had a lot of fun since I used it, and I'm sure you do, too. At least you don't have to reject it deliberately.
In a worst-case scenario, there is a Pyjnius that allows you to do this:
From jnius import autoclass System = autoclass ('java.lang.System') System.out.println (' Hello, Worldwide') This is the answer to the question about the introduction to Python which is suitable for Java developers. I hope the above content can be of some help to you. If you still have a lot of doubts to be solved, you can follow the industry information channel for more related knowledge.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.