A compilation of @pythonetc, september 2018

3r3-31. 3r33417. A compilation of @pythonetc, september 2018 3r33434.  
3r33417. This is the fourth selection of tips on Python and programming from my channel. @pythonetc .
3r33417. Previous selections:
August 2018
July 2013 r3r336.
June 2013 r3r336.
Override and overload
3r33417. There are two concepts that are easily confused: overriding and overloading.
3r33417. Overriding happens when a child class defines a method that is already provided by the parent classes, and thereby replaces it. In some languages, it is required to explicitly mark the overriding method (in C # the modifier 3r33422. Override ) Is used, and in some languages ​​this is done at will (abstract 3r3439. @Override 3r3439. In Java). Python does not require the use of a special modifier and does not provide for standard tagging of such methods (someone for the sake of readability uses a custom decorator @Override , Which does nothing). 3r33434.  
3r33417. Overloading is another story. This term refers to the situation when there are several functions with the same name, but with different signatures. Overloading is possible in Java and C ++, it is often used to provide default arguments: 3r33434.  
3r33427. 3r33434. class foo {
public static void main (String[]args) {
System.out.println (Hello ());
public static String Hello () {
return Hello ("world");
public static String Hello (String name) {
return "Hello," + name;
} 3r33440. 3r33434.  
3r33417. Python does not support searching functions by signature, only by name. Of course, you can write code that explicitly analyzes the types and number of arguments, but it will look awkward, and this practice is best avoided: 3r32424. 3r33434.  
3r33427. 3r33434. def quadrilateral_area (* args):
if len (args) == 4:
quadrilateral = Quadrilateral (* args)
elif len (args) == 1:
quadrilateral = args[0]
raise TypeError ()
return quadrilateral.area () 3r33440. 3r33434.  
3r33417. If you need type hints, use the module. typing with decorator @overload : 3r33424. 3r33434.  
3r33427. 3r33434. from typing import overload
def quadrilateral_area (
q: Quadrilateral
) -> float:
def quadrilateral_area (
p1: Point, p2: Point,
p3: Point, p4: Point
) -> float: 3r3439. 3r33440. 3r33434.  


3r33417. collections.defaultdict allows you to create a dictionary that returns the default value if the requested key is missing (instead of throwing KeyError ). To create 3r33422. defaultdict You need to provide not just a default value, but a factory of such values. 3r33434.  
3r33417. So you can create a dictionary with a virtually infinite number of nested dictionaries, which will allow you to use constructions like 3r32234. d[a] [b] [c] [z] . 3r33434.  
3r33427. 3r33434. def infinite_dict ():
return defaultdict (infinite_dict)
d = infinite_dict ()
d[1] [2] [3] [4]= 10
dict (d[1] [2] [3] [5])
{} 3r3439. 3r33440. 3r33434.  
3r33417. This behavior is called “autovivification,” a term that comes from Perl. 3r33434.  
3r3158. Instantiation 3r33434.  
3r33417. Instantiating objects involves two important steps. First, the method is called from the class. __new__3r3439. which creates and returns a new object. Then from it, Python calls the method. __init__3r3439. which sets the initial state of this object. 3r33434.  
3r33417. However, __init__3r3439. will not be called if __new__3r3439. returns an object that is not an instance of the original class. In this case, the object could have been created by another class, and therefore __init__3r3439. already called on the object: 3r33434.  
3r33427. 3r33434. class Foo:
def __new __ (cls, x):
return dict (x = x)
def __init __ (self, x):
print (x) # Never called
print (foo (0))
3r33440. 3r33434.  
3r33417. This also means that you should not create instances of the same class in 3r33422. __new__3r3439. using the usual constructor ( Foo () ). This may lead to a rerun of __init__3r3439. , or even to infinite recursion. 3r33434.  
3r33417. Infinite recursion: 3r33434.  
3r33427. 3r33434. class Foo:
def __new __ (cls, x):
Return Foo (-x) # Recursion
3r33440. 3r33434.  
3r33417. Double version __init__3r3439. : 3r33424. 3r33434.  
3r33427. 3r33434. class Foo:
def __new __ (cls, x):
if x < 0:
return foo (-x)
Return super () .__ new __ (cls)
def __init __ (self, x):
print (x) 3r3451. self._x = x
3r33440. 3r33434.  
3r33417. The correct way: 3r33434.  
3r33427. 3r33434. class Foo:
def __new __ (cls, x):
if x < 0:
return cls .__ new __ (cls, -x)
Return super () .__ new __ (cls)
def __init __ (self, x):
print (x) 3r3451. self._x = x
3r33440. 3r33434.  

Operator[]and slices

3r33417. In Python, you can override the operator.[] by defining the magic method __getitem__ . For example, you can create an object that virtually contains an infinite number of duplicate elements: 3r33434.  
3r33427. 3r33434. class Cycle:
def __init __ (self, lst):
self._lst = lst
def __getitem __ (self, index):
return self._lst[
index % len(self._lst)
print (Cycle (['a', 'b', 'c'])[100]) # 'b'
3r33440. 3r33434.  
3r33417. The unusual thing here is that the operator [] supports unique syntax. With it, you can get not only [2] but [2:10] , [2:10:2] , [2::2] and even [:] . The semantics of the operator is:[start:stop:step]however, you can use it in any other way to create custom objects. 3r33434.  
3r33417. But if you call using this syntax __getitem__ What will it get as an index parameter? That is why slice objects exist. 3r33434.  
3r33427. 3r33434. In: class Inspector:
: def __ getitem __ (self, index):
: print (index)
In: Inspector ()[1]
In: Inspector ()[1:2]
slice (? ? None)
In: Inspector ()[1:2:3]
slice (? ? 3)
In: Inspector ()[:]
slice (None, None, None)
3r33440. 3r33434.  
3r33417. You can even combine the syntaxes of tuples and slices: 3r33434.  
3r33427. 3r33434. In: Inspector ()[:, 0, :]
(slice (None, None, None), ? slice (None, None, None)) 3r3439. 3r33440. 3r33434.  
3r33417. slice Does nothing, only stores attributes start , stop and 3r33422. step
. 3r33434.  
3r33427. 3r33434. In: s = slice (? ? 3)
In: s.start
Out: 1
In: s.stop
Out: 2
In: s.step
Out: 3 3r33440. 3r33434.  
3r33354. Interruption of asyncio corticles 3r33434.  
3r33417. Any coroutine played (coroutine) asyncio can be interrupted using the method. cancel () . At the same time, 3–3–3422 will be sent to Korutin. CanceledError As a result, this and all associated Korutins will be interrupted until the error is caught and suppressed. 3r33434.  
3r33417. CanceledError - subclass Exception , which means you can accidentally catch it using a combination of try except Exception designed to catch "any mistakes." To safely catch a coroutine, you have to do this: 3r33434.  
3r33427. 3r33434. try:
await action ()
except asyncio.CancelledError:
except Exception: 3r3451. logging.exception ('action failed') 3r33440. 3r33434.  
3r33333. Planning for execution 3r33434.  
3r33417. To schedule the execution of some code at a specific time in 3r33422. asyncio usually create a task that performs await asyncio.sleep (x) : 3r33424. 3r33434.  
3r33427. 3r33434. import asyncio
async def do (n = 0):
print (n)
await asyncio.sleep (1)
loop.create_task (do (n + 1))
loop.create_task (do (n + 1))
loop = asyncio.get_event_loop ()
loop.create_task (do ())
loop.run_forever () 3r33440. 3r33434.  
3r33417. But creating a new task can be expensive, and you don’t have to do it if you don’t plan to perform asynchronous operations (like the function 3r32222. Do 3r34399 in my example). Instead, you can use the functions loop.call_later and 3r33422. loop.call_at that allow you to schedule an asynchronous callback call: 3r32424. 3r33434.  
3r33427. 3r33434. import asyncio
def do (n = 0):
print (n)
loop = asyncio.get_event_loop ()
loop.call_later (? do, n + 1)
loop.call_later (? do, n + 1)
loop = asyncio.get_event_loop ()
do ()
loop.run_forever () 3r33440.
! function (e) {function t (t, n) {if (! (n in e)) {for (var r, a = e.document, i = a.scripts, o = i.length; o-- ;) if (-1! == i[o].src.indexOf (t)) {r = i[o]; break} if (! r) {r = a.createElement ("script"), r.type = "text /jаvascript", r.async =! ? r.defer =! ? r.src = t, r.charset = "UTF-8"; var d = function () {var e = a.getElementsByTagName ("script")[0]; e.parentNode.insertBefore (r, e)}; "[object Opera]" == e.opera? a.addEventListener? a.addEventListener ("DOMContentLoaded", d,! 1): e.attachEvent ("onload", d ): d ()}}} t ("//mediator.mail.ru/script/2820404/"""_mediator") () (); 3r33434.
+ 0 -

Add comment