current position:Home>Deep understanding of Python features

Deep understanding of Python features

2022-01-30 07:22:45 cxapython

Little knowledge , Great challenge ! This article is participating in “ A programmer must have a little knowledge ” Creative activities .

This article has participated in  「 Digging force Star Program 」 , Win a creative gift bag , Challenge creation incentive fund

image.png

1. Assertion

Python The assertion statement is a debugging aid , Not a mechanism for handling runtime errors .

assert Condition is False Is triggered when , The following content is the error information .

import sys
​
assert sys.version_info >= (3, 7), " Please be there. Python3.7 And above environmental execution "
 Copy code 

If the minimum requirement for this project is Python3.7 Environment , So if you use Python3.6 To run this project , This error message will appear .

Traceback (most recent call last):
  File "/Users/chennan/pythonproject/demo/nyandemo.py", line 3, in <module>
    assert sys.version_info > (3, 7), " Please be there. Python3.7 The above environment is implemented "
AssertionError:  Please be there. Python3.7 The above environment is implemented 
 Copy code 

Early termination of the project

2. Cleverly place commas

Reasonably format the elements in the list , Easier to maintain

We usually do this when we write a list

l = ["apple", "banana", "orange"]
 Copy code 

Use the following methods to distinguish each item more clearly , Habitually add a comma at the end , Prevent missing commas when adding elements next time , It looks more Pythonic

l = [
    "apple", 
    "banana", 
    "orange",
]
 Copy code 

3. Underline 、 Double underline and other

Pre single underline : _var

1. It's a convention , Methods and variables with a single preceding underscore are used internally only

2. The use of wildcard guided packages from xx import * such , You don't need to import variables with a single underscore in front of them , Unless it defines __all__ Covering this behavior .PEP8 It is generally not recommended to guide the package in this way .

Post single underline : var_

If the variable name used is Python Keywords in , For example, to declare class This variable , We can put a single underline after it at this time class_

This is also PEP8 Agreed in

Leading double underline : __var

      Leading double underscores will make  Python  The interpreter overrides the property name , Prevent from being overwritten by names in subclasses .
class Test:
    def __init__(self):
        self.foo = 11
        self.__bar = 2
​
​
t = Test()
print(dir(t))
 Copy code 

Looking at the properties of the class, you can find self.__bar Change into _Test__bar, This is also called name rewriting (name mangling), The interpreter changes the name of the variable , Prevent naming conflicts when expanding this type .

['_Test__bar', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'foo']
 Copy code 

If you want to visit __bar, What shall I do? , We can go through t._Test__bar Visit .

If we inherit Test Then rewrite __bar What will happen

class ExtendTest(Test):
    def __init__(self):
        super().__init__()
        self.foo = "overridden"
        self.__bar = "overridden"
​
​
et = ExtendTest()
print(et.foo)
print(et.__bar)
 Copy code 

It turns out that something went wrong

AttributeError: 'ExtendTest' object has no attribute '__bar'
 Copy code 

The reason is the same as before , Because the interpreter puts __bar The name of is changed to prevent the variable of the parent class from being overwritten .

We can access these two classes separately __bar Find that they exist at the same time , It's really not covered .

print(et._Test__bar)
print(et._ExtendTest__bar)
 Copy code 

Get the results

2
overridden
 Copy code 

By the way __bar In English, it is generally called dunderbar.

Except for double underlined variables , Double underlined method names can also be overwritten by interpreter names .

class ManglingMethod:
    def __mangled(self):
        return 42

    def call_it(self):
        return self.__mangled()

md = ManglingMethod()
md.call_it()
md.__mangled()
 Copy code 

After getting the error message

AttributeError: 'ManglingMethod' object has no attribute '__mangled'
 Copy code 

Double underline before and after : var

The so-called magic method , Its name will not be changed by the interpreter , However, as far as naming conventions are concerned, it is best to avoid using such formal variable and method names

Underline : _

1._ It can indicate that the variable is temporary or irrelevant

for _ in rang(5):
    print("hello")
 Copy code 

2. It can also be used as a thousand separator before a number

for i in range(1000_000):
    print(i)
 Copy code 

3. It can be used as a placeholder when unpacking tuples .

car = ("red", "auto", 12, 332.4 )
color,_,_,mileage = car
print(color)
print(_mileage)
 Copy code 

4. If you use command line mode ,_ You can get the results of the previous calculation

>>>  20+5
25
>>> _
25
>>> print(_)
25
 Copy code 

4. Custom exception classes

We have the following code

def validate(name):
    if len(name) < 10:
        raise ValueError
 Copy code 

If you call this method in other files ,

validate("lisa")
 Copy code 

When you don't understand the function of this method , If the name verification fails , The call stack will print out the following information

Traceback (most recent call last):
  File "/Users/chennan/pythonproject/demo/nyandemo.py", line 57, in <module>
    validate("lisa")
  File "/Users/chennan/pythonproject/demo/nyandemo.py", line 55, in validate
    raise ValueError
ValueError
 Copy code 

The information in this stack debug backtrace indicates , An incorrect value has occurred , But I don't know why I made a mistake , So we need to follow up at this time validate To find out ,

At this time, we can define an exception class ourselves

class NameTooShortException(ValueError):
   def __str__(self):
       return " The length of the entered name must be greater than or equal to 10"



def validate(name):
    if len(name) < 10:
        raise NameTooShortException(name)

validate("lisa")
 Copy code 

So if there's another mistake , You can know why you're wrong , At the same time, the calling method is also convenient to catch the specified exception , Don't use ValueError.

try:
    validate("lisa")
except NameTooShortException as e:
    print(e)
 Copy code 

5.Python Bytecode

Cpython When the interpreter executes , First, it is translated into a series of bytecode instructions . Bytecode is Python Intermediate language of virtual machine , It can improve the execution efficiency of the program

Cpython Do not directly execute human readable source code , Instead, it performs a compact number generated by compiler parsing and syntax semantic analysis 、 Variables and references .

such , It can save time and memory when executing the same program again . Because the bytecode generated by the compilation step will be .pyc and .pyo The form of file is cached on the hard disk , Therefore, it is better to execute bytecode than to execute the same code again Python Files are faster .

def greet(name):
    return 'hello, ' + name + '!'


#__code__ Can get greet Virtual machine instructions used in the function , Constants and variables 
gc = greet.__code__
print(gc.co_code)  #  Command stream 

print(gc.co_consts)  #  Constant 

print(gc.co_varnames)  #  Parameters transmitted 
dis.dis(greet)
 Copy code 

result

b'd\x01|\x00\x17\x00d\x02\x17\x00S\x00'
(None, 'hello, ', '!')
('name',)
 70           0 LOAD_CONST               1 ('hello, ')
              2 LOAD_FAST                0 (name)
              4 BINARY_ADD
              6 LOAD_CONST               2 ('!')
              8 BINARY_ADD
             10 RETURN_VALUE
 Copy code 

The interpreter is indexing 1 It's about ('hello, ') Find constants , And put it on the stack , And then name Put the contents of the variable on the stack Cpython Virtual machine is based on stack virtual machine , Stack is the internal data structure of virtual machine . The stack only supports two actions : Push and pull Push : Add a value to the top of the stack Out of the stack : Delete and return the value at the top of the stack .

Suppose the stack is initially empty , Before executing the first two opcodes (opcode) after , Virtual content (0 It's the top element ) For example, we introduced name by lisa.

0: 'lisa'
1: 'hello, '
 Copy code 

BINARY_ADD Instruction pops two string values from the stack , And connect them Then push the result onto the stack again .

0:'hello, lisa'
 Copy code 

Then the next LOAD_CONST take '!' Push to stack . The result at this point

0:'!'
1:'hello, lisa'
 Copy code 

next BINARY_ADD The opcode pops the two strings out of the stack again, connects them, and then pushes them into the stack , Generate the final result

0:'hello, lisa!'
 Copy code 

Last bytecode RETURN_VALUE , Tell the virtual machine that what is currently at the top of the stack is the return value of the function .

The original text comes from my Zhihu column :zhuanlan.zhihu.com/p/267563522

copyright notice
author[cxapython],Please bring the original link to reprint, thank you.
https://en.pythonmana.com/2022/01/202201300722307009.html

Random recommended