Python Learning Record day8

Keywords: Python Attribute

title: Python Learning Record day8
tags: python
author: Chinge Yang
date: 2017-02-27
---

Python Learning Record day8

@ (Learning) [python]

[TOC]

1. Static method

@ Static method decorator can turn its decoration method into a static method. Static methods, which are nominally categorized, can not actually access any attributes of classes or instances in static methods.

#!/usr/bin/env python
# _*_coding:utf-8_*_
'''
 * Created on 2017/2/27 20:18.
 * @author: Chinge_Yang.
'''


class Cat(object):
    def __init__(self, name):
        self.name = name

    @staticmethod  # Turn eat method into static method
    def eat(self):
        print("%s is eating" % self.name)
 

d = Cat("bana")
d.eat()

The above call makes the following mistake: eat needs a self parameter, but it is not passed when it is called. Yes, when eat becomes a static method, it will not automatically pass the instance itself as a parameter to self when it is called through the instance.

staticmethod.py", line 19, in <module>
    d.eat()
TypeError: eat() missing 1 required positional argument: 'self'

There are two ways to make the above code work properly

  1. Actively pass the instance itself to eat method, d.eat(d)
  2. Remove the self parameter from the eat method, but this also means that other variables in the instance cannot be invoked through self. in eat.
#!/usr/bin/env python
# _*_coding:utf-8_*_
'''
 * Created on 2017/2/27 20:18.
 * @author: Chinge_Yang.
'''


class Cat(object):
    def __init__(self, name):
        self.name = name

    @staticmethod  # Turn eat method into static method
    def eat():   # Remove self here
        print("is eating")


d = Cat("bana")
d.eat()

The 2. method

Class method is implemented by @classmethod decorator It can only access class variables, not instance variables.

#!/usr/bin/env python
# _*_coding:utf-8_*_
'''
 * Created on 2017/2/27 20:18.
 * @author: Chinge_Yang.
'''


class Cat(object):
    name = "Class variables"  # Variables need to be defined in classes
    def __init__(self, name):
        self.name = name

    @classmethod  # Change eat method into class method
    def eat(self):  # Here is self
        print("%s is eating" % self.name)


d = Cat("bana")
d.eat()

Result: The parameters passed in by the instance can not be used. The inner variables of the class are used. Because no name is defined in the class, there will be an error prompt.

Class variable is eating

3. Attribute Method

Property method turns a method into a static property by @property.

#!/usr/bin/env python
# _*_coding:utf-8_*_
'''
 * Created on 2017/2/27 20:18.
 * @author: Chinge_Yang.
'''


class Cat(object):
    def __init__(self, name):
        self.name = name

    @property # Change eat method into attribute method
    def eat(self):
        print("%s is eating" % self.name)


d = Cat("bana")
d.eat   # No brackets here

What application scenarios are there to turn a method into a static property?
For example, if you want to know the current status of a flight, whether it has arrived, delayed, cancelled or flown away, you have to go through the following steps to know the status:

  1. Connect airline API queries
  2. Parse the query results
  3. Return the results to your users

So the value of this status attribute is the result of a series of actions, so every time you call it, it actually needs a series of actions to return your results, but these actions need not be concerned by the user, the user only needs to call this attribute.

class Flight(object):
    def __init__(self,name):
        self.flight_name = name


    def checking_status(self):
        print("checking flight %s status " % self.flight_name)
        return  1

    @property
    def flight_status(self):
        status = self.checking_status()
        if status == 0 :
            print("flight got canceled...")
        elif status == 1 :
            print("flight is arrived...")
        elif status == 2:
            print("flight has departured already...")
        else:
            print("cannot confirm the flight status...,please check later")


f = Flight("CA980")
f.flight_status

Since this flight_status is already an attribute, how can we assign it a value?
You need to adorn it with the @proerty.setter decorator At this point, you need to write a new method to change the flight_status.

class Flight(object):
    def __init__(self,name):
        self.flight_name = name


    def checking_status(self):
        print("checking flight %s status " % self.flight_name)
        return  1


    @property
    def flight_status(self):
        status = self.checking_status()
        if status == 0 :
            print("flight got canceled...")
        elif status == 1 :
            print("flight is arrived...")
        elif status == 2:
            print("flight has departured already...")
        else:
            print("cannot confirm the flight status...,please check later")
    
    @flight_status.setter #modify
    def flight_status(self,status):
        status_dic = {
            0 : "canceled",
            1 :"arrived",
            2 : "departured"
        }
        print("\033[31;1mHas changed the flight status to \033[0m",status_dic.get(status) )

    @flight_status.deleter  #delete
    def flight_status(self):
        print("status got removed...")

f = Flight("CA980")
f.flight_status
f.flight_status =  2 #Trigger @flight_status.setter 
del f.flight_status #Trigger @flight_status.deleter 

Note that there is also an @flight_status.deleter in the code above. It allows you to delete this property.

4. Special member methods of classes

4.1 _doc_ Represents descriptive information of classes

class Foo:
    """ Description class information """
 
    def func(self):
        pass
         
print(Foo.__doc__)

Result:

Description class information

4.2 _module_ and _class__

_ Modul_ denotes the object of the current operation in that module

_ What class__ represents the object of the current operation

cat lib/c.py

class Foo(object):

    def __init__(self):
        self.name = 'ygqygq2'  

cat index.py

from lib.c import Foo

obj = Foo()
print(obj.__module__)  # Output lib.c, i.e. output module
print(obj.__class__)  # Output < class'lib.c.Foo'>, that is, output class

4.3__init_ Construction Method

_ The init_ constructor automatically triggers execution when it creates objects through classes.

4.4 _del_ destructive method

Destruction method, which automatically triggers execution when an object is released in memory.

Note: This method generally does not need to be defined, because Python is a high-level language, programmers do not need to care about memory allocation and release when using it, because this work is handed to Python interpreter to perform, so the call of destructor is triggered automatically by interpreter when garbage collection is carried out.

  

4.5 call call method

Objects are parenthesed to trigger execution.

class Foo(object):
 
    def __init__(self):
        pass
     
    def __call__(self, *args, **kwargs):
        print('__call__')
 
 
obj = Foo() # Execute _init__
obj()       # Execution of _call__
Note: The execution of the constructor is triggered by the creation object, that is, the object = the class name (); and the execution of the _call_ method is triggered by the object followed by parentheses, that is, the object () or the class ()) ().

4.6 __dict__

_ dict_ View all members of a class or object

class Province(object):

    country = 'China'

    def __init__(self, name, count):
        self.name = name
        self.count = count

    def func(self, *args, **kwargs):
        print('func')

# Get the members of the class, that is, static fields, methods, and
print(Province.__dict__)
# Output: {''uuuinit_'::::{{{'''uinit____ at 0x106a210d0>,'country'':'China'','func': < functional province. func'< functional province. func at 0x106a21488>,'doc_u': None,''_\\u':<attribute'_dict___\u\\_\__weakref_': <attribute'_weakref_ of'Province'objects>}


obj1 = Province('HeBei',10000)
print (obj1.__dict__)
# Get the members of object obj1
# Output: {count': 10000,'name':'HeBei'}

obj2 = Province('HeNan', 3888)
print(obj2.__dict__)
# Get the members of object obj1
# Output: {count': 3888,'name':'HeNan'}

4.7__str_ Method

If a _str_ method is defined in a class, the return value of the method is output by default when the object is printed.

class Foo(object):
 
    def __str__(self):
        return 'ygqygq2'
 
 
obj = Foo()
print(obj)
# Output: ygqygq2

4.8 __getitem__,__setitem__,__delitem__

Used for indexing operations, such as dictionaries. The above means to get, set and delete data, respectively.

class Foo(object):
    def __getitem__(self, key):
        print('__getitem__', key)

    def __setitem__(self, key, value):
        print('__setitem__', key, value)

    def __delitem__(self, key):
        print('__delitem__', key)


obj = Foo()

result = obj['k1']  # Automatic Trigger Execution _getitem__
obj['k2'] = 'ygqygq2'  # Automatic Trigger Execution _setitem__
del obj['k1']

Result:

__getitem__ k1
__setitem__ k2 ygqygq2
__delitem__ k1

4.9 __new__ \ __metaclass__

class Foo(object):
 
 
    def __init__(self,name):
        self.name = name
 
f = Foo("ygqygq2")
print(type(Foo))
print(type(f))

Result:

<class 'type'>
<class '__main__.Foo'>

In the above code, obj is an object instantiated by the Foo class. In fact, not only is obj an object, but the Foo class itself is an object, because everything in Python is an object.

If everything is an object according to the theory that obj objects are created by executing the construction method of Foo class, then Foo class objects should also be created by executing the construction method of a class.

print type(f) # output: < class'main. Foo'> indicates that the obj object is created by the Foo class
print type(Foo) # output: < class'type'> indicates that the Foo class object is created by the type class
So, the f object is an instance of the Foo class, and the Foo object is an instance of the type class, that is, the Foo object is created by the construction method of the type class.

There are two ways to create a class:
1. Common way

class Foo(object):
  
    def func(self):
        print('hello')

2. Special ways

def func(self):
    print('hello')

Foo = type('Foo',(object,), {'func': func})

#type first parameter: class name
#The second parameter of type: the base class of the current class
#The third parameter of type: the members of the class

With the constructor, the class is generated by instantiating the type class.

So the problem arises. Classes are generated by instantiation of type classes by default. How do you create classes in type classes? How do classes create objects?
Answer: There is an attribute _metaclass_ in the class, which is used to indicate who created the class instantiated, so we can set a derived class of type class for _metaclass_ to see the process of class creation.

The order of class generation and invocation is _new_ - > _call_ - > _init__

Posted by biltong on Wed, 10 Apr 2019 16:45:31 -0700