Bound methods of classes and objects and non-binding approach

Bound methods of classes and objects and non-binding approach

The method defined in the class can be divided into two categories: binding method and unbound methods. Wherein binding method can be divided into a method to bind to the target and bind to the class method.

A binding method

1.1 bound method object

There is no way by any decorator modified approach is bound to an object in the class, these methods specifically for custom objects.

class Person:
    country = "China"

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

    def speak(self):
        print(self.name + ', ' + str(self.age))


p = Person('Kitty', 18)
print(p.__dict__)
{'name': 'Kitty', 'age': 18}
print(Person.__dict__['speak'])
<function Person.speak at 0x10f0dd268>

Methods speak shall be bound to an object, this method is not the name of the object in space, the name space but in class. Method to bind to the object by calling the object, the process will automatically pass a value, the current object will automatically pass to the method of the first parameter (self, typically called self, other names can also be written); if used class called, the first argument passed by value manually.

p = Person('Kitty', 18)
p.speak()  # 通过对象调用
Kitty, 18
Person.speak(p)  # 通过类调用
Kitty, 18

1.2 class binding method

@Classmethod class using the modified method is bound to the methods of the class. Such methods are customized specifically for the class. When bound to the methods of the class by calling the class name, it will be the first class itself as one of the parameters passed to the class method.

class Operate_database():
    host = '192.168.0.5'
    port = '3306'
    user = 'abc'
    password = '123456'

    @classmethod
    def connect(cls):  # 约定俗成第一个参数名为cls,也可以定义为其他参数名
        print(cls)
        print(cls.host + ':' + cls.port + ' ' + cls.user + '/' + cls.password)


Operate_database.connect()
<class '__main__.Operate_database'>
192.168.0.5:3306 abc/123456

May be invoked by the object, the first parameter passed only the default object or the corresponding class.

Operate_database().connect()  # 输出结果一致
<class '__main__.Operate_database'>
192.168.0.5:3306 abc/123456

Second, the non-binding approach

@Staticmethod using a modified method is, within the class of non-binding method, and ordinary methods such defined functions without distinction, not tied to an object or class, anyone can call, automatically and without the effect of the traditional values.

import hashlib


class Operate_database():
    def __init__(self, host, port, user, password):
        self.host = host
        self.port = port
        self.user = user
        self.password = password

    @staticmethod
    def get_passwrod(salt, password):
        m = hashlib.md5(salt.encode('utf-8'))  # 加盐处理
        m.update(password.encode('utf-8'))
        return m.hexdigest()
hash_password = Operate_database.get_passwrod('lala', '123456')  # 通过类来调用
print(hash_password)
f7a1cc409ed6f51058c2b4a94a7e1956
p = Operate_database('192.168.0.5', '3306', 'abc', '123456')
hash_password = p.get_passwrod(p.user, p.password)  # 也可以通过对象调用
print(hash_password)
0659c7992e268962384eb17fafe88364

In short, non-binding approach is to put the common methods within the class.

Third, exercise

Suppose we now have a demand, Mysql need to instantiate the object can read data from a file in settings.py.

# settings.py
IP = '1.1.1.10'
PORT = 3306
NET = 27
# test.py
import uuid


class Mysql:
    def __init__(self, ip, port, net):
        self.uid = self.create_uid()
        self.ip = ip
        self.port = port
        self.net = net

    def tell_info(self):
        """查看ip地址和端口号"""
        print('%s:%s' % (self.ip, self.port))

    @classmethod
    def from_conf(cls):
        return cls(IP, NET, PORT)

    @staticmethod
    def func(x, y):
        print('不与任何人绑定')

    @staticmethod
    def create_uid():
        """随机生成一个字符串"""
        return uuid.uuid1()


# 默认的实例化方式:类名()
obj = Mysql('10.10.0.9', 3307, 27)
obj.tell_info()
10.10.0.9:3307

3.1 Binding Methods Summary

If the function code requires an external body of the incoming class, then this function should be defined as a method to bind to the class
if needed function body incoming external object, then this function should be defined as a method of binding to the subject

# 一种新的实例化方式:从配置文件中读取配置完成实例化
obj1 = Mysql.from_conf()
obj1.tell_info()
1.1.1.10:27
print(obj.tell_info)
<bound method Mysql.tell_info of <__main__.Mysql object at 0x10f469240>>
print(obj.from_conf)
<bound method Mysql.from_conf of <class '__main__.Mysql'>>

3.2 Summary of non-binding approach

If the non-binding method requires neither an external function body does not require an external incoming class object passed in it should be defined as the function / normal function

obj.func(1, 2)
不与任何人绑定
Mysql.func(3, 4)
不与任何人绑定
print(obj.func)
<function Mysql.func at 0x10f10e620>
print(Mysql.func)
<function Mysql.func at 0x10f10e620>
print(obj.uid)
a78489ec-92a3-11e9-b4d7-acde48001122

Guess you like

Origin www.cnblogs.com/Dr-wei/p/11850973.html