如何调用模块对象?

问题描述

我尝试在 Python 中运行此 Ant Colony 算法代码 (const str ='username:password\r\n' const username = str.split(:)[0]; const password = str.split(:)[1].replace(/[\r\n]+/g,''); ):

const str =`username:password\r\n
username:password\r\n
username:password\r\n`;

const res = str.split(/[\r\n]/g)
               .filter(l=>l!=="")
               .map(s=>({username:s.split(':')[0],password:s.split(':')[1]}));

console.log(res)
// [{username:'username',password:'password'},...];

我的模块测试文件是:

ant_colony.py

但是运行的时候出现这个错误

from threading import Thread

class ant_colony:
    class ant(Thread):
        def __init__(self,init_location,possible_locations,pheromone_map,distance_callback,alpha,beta,first_pass=False):
            
            Thread.__init__(self)
            
            self.init_location = init_location
            self.possible_locations = possible_locations            
            self.route = []
            self.distance_traveled = 0.0
            self.location = init_location
            self.pheromone_map = pheromone_map
            self.distance_callback = distance_callback
            self.alpha = alpha
            self.beta = beta
            self.first_pass = first_pass
            
            self._update_route(init_location)
            
            self.tour_complete = False
            
        def run(self):
            
            while self.possible_locations:
                next = self._pick_path()
                self._traverse(self.location,next)
                
            self.tour_complete = True
        
        def _pick_path(self):
            
            if self.first_pass:
                import random
                return random.choice(self.possible_locations)
            
            attractiveness = dict()
            sum_total = 0.0
            
            for possible_next_location in self.possible_locations:
                
                pheromone_amount = float(self.pheromone_map[self.location][possible_next_location])
                distance = float(self.distance_callback(self.location,possible_next_location))
                
                
                attractiveness[possible_next_location] = pow(pheromone_amount,self.alpha)*pow(1/distance,self.beta)
                sum_total += attractiveness[possible_next_location]
            
            
            if sum_total == 0.0:
                
                def next_up(x):
                    import math
                    import struct
                    
                    if math.isnan(x) or (math.isinf(x) and x > 0):
                        return x

                    
                    if x == 0.0:
                        x = 0.0

                    n = struct.unpack('<q',struct.pack('<d',x))[0]
                    
                    if n >= 0:
                        n += 1
                    else:
                        n -= 1
                    return struct.unpack('<d',struct.pack('<q',n))[0]
                    
                for key in attractiveness:
                    attractiveness[key] = next_up(attractiveness[key])
                sum_total = next_up(sum_total)
            
            
            import random
            toss = random.random()
                    
            cummulative = 0
            for possible_next_location in attractiveness:
                weight = (attractiveness[possible_next_location] / sum_total)
                if toss <= weight + cummulative:
                    return possible_next_location
                cummulative += weight
        
        def _traverse(self,start,end):
            
            self._update_route(end)
            self._update_distance_traveled(start,end)
            self.location = end
        
        def _update_route(self,new):
            
            self.route.append(new)
            self.possible_locations.remove(new)
            
        def _update_distance_traveled(self,end):
            
            self.distance_traveled += float(self.distance_callback(start,end))
    
        def get_route(self):
            if self.tour_complete:
                return self.route
            return None
            
        def get_distance_traveled(self):
            if self.tour_complete:
                return self.distance_traveled
            return None
        
    def __init__(self,nodes,start=None,ant_count=50,alpha=.5,beta=1.2,pheromone_evaporation_coefficient=.40,pheromone_constant=1000.0,iterations=80):
        
        if type(nodes) is not dict:
            raise TypeError("nodes must be dict")
        
        if len(nodes) < 1:
            raise ValueError("there must be at least one node in dict nodes")
        
        
        self.id_to_key,self.nodes = self._init_nodes(nodes)
        
        self.distance_matrix = self._init_matrix(len(nodes))
        
        self.pheromone_map = self._init_matrix(len(nodes))
        
        self.ant_updated_pheromone_map = self._init_matrix(len(nodes))
        
        
        if not callable(distance_callback):
            raise TypeError("distance_callback is not callable,should be method")
            
        self.distance_callback = distance_callback
        
        
        if start is None:
            self.start = 0
        else:
            self.start = None
            #init start to internal id of node id passed
            for key,value in self.id_to_key.items():
                if value == start:
                    self.start = key
            
            #if we didn't find a key in the nodes passed in,then raise
            if self.start is None:
                raise KeyError("Key: " + str(start) + " not found in the nodes dict passed.")
        
        
        if type(ant_count) is not int:
            raise TypeError("ant_count must be int")
            
        if ant_count < 1:
            raise ValueError("ant_count must be >= 1")
        
        self.ant_count = ant_count
        
        
        if (type(alpha) is not int) and type(alpha) is not float:
            raise TypeError("alpha must be int or float")
        
        if alpha < 0:
            raise ValueError("alpha must be >= 0")
        
        self.alpha = float(alpha)
        
        
        if (type(beta) is not int) and type(beta) is not float:
            raise TypeError("beta must be int or float")
            
        if beta < 1:
            raise ValueError("beta must be >= 1")
            
        self.beta = float(beta)
        
        
        if (type(pheromone_evaporation_coefficient) is not int) and type(pheromone_evaporation_coefficient) is not float:
            raise TypeError("pheromone_evaporation_coefficient must be int or float")
        
        self.pheromone_evaporation_coefficient = float(pheromone_evaporation_coefficient)
        
        #pheromone_constant
        if (type(pheromone_constant) is not int) and type(pheromone_constant) is not float:
            raise TypeError("pheromone_constant must be int or float")
        
        self.pheromone_constant = float(pheromone_constant)
        
        #iterations
        if (type(iterations) is not int):
            raise TypeError("iterations must be int")
        
        if iterations < 0:
            raise ValueError("iterations must be >= 0")
            
        self.iterations = iterations
        
        #other internal variable init
        self.first_pass = True
        self.ants = self._init_ants(self.start)
        self.shortest_distance = None
        self.shortest_path_seen = None
        
    def _get_distance(self,end):
        
        if not self.distance_matrix[start][end]:
            distance = self.distance_callback(self.nodes[start],self.nodes[end])
            
            if (type(distance) is not int) and (type(distance) is not float):
                raise TypeError("distance_callback should return either int or float,saw: "+ str(type(distance)))
            
            self.distance_matrix[start][end] = float(distance)
            return distance
        return self.distance_matrix[start][end]
        
    def _init_nodes(self,nodes):
        
        id_to_key = dict()
        id_to_values = dict()
        
        id = 0
        for key in sorted(nodes.keys()):
            id_to_key[id] = key
            id_to_values[id] = nodes[key]
            id += 1
            
        return id_to_key,id_to_values
        
    def _init_matrix(self,size,value=0.0):
        
        ret = []
        for row in range(size):
            ret.append([float(value) for x in range(size)])
        return ret
    
    def _init_ants(self,start):
        
        #allocate new ants on the first pass
        if self.first_pass:
            return [self.ant(start,self.nodes.keys(),self.pheromone_map,self._get_distance,self.alpha,self.beta,first_pass=True) for x in range(self.ant_count)]
        #else,just reset them to use on another pass
        for ant in self.ants:
            ant.__init__(start,self.beta)
    
    def _update_pheromone_map(self):
        
        #always a square matrix
        for start in range(len(self.pheromone_map)):
            for end in range(len(self.pheromone_map)):
                #decay the pheromone value at this location
                #tau_xy <- (1-rho)*tau_xy   (ACO)
                self.pheromone_map[start][end] = (1-self.pheromone_evaporation_coefficient)*self.pheromone_map[start][end]
                
                #then add all contributions to this location for each ant that travered it
                #(ACO)
                #tau_xy <- tau_xy + delta tau_xy_k
                #   delta tau_xy_k = Q / L_k
                self.pheromone_map[start][end] += self.ant_updated_pheromone_map[start][end]
    
    def _populate_ant_updated_pheromone_map(self,ant):
        
        route = ant.get_route()
        for i in range(len(route)-1):
            #find the pheromone over the route the ant traversed
            current_pheromone_value = float(self.ant_updated_pheromone_map[route[i]][route[i+1]])
        
            #update the pheromone along that section of the route
            #(ACO)
            #   delta tau_xy_k = Q / L_k
            new_pheromone_value = self.pheromone_constant/ant.get_distance_traveled()
            
            self.ant_updated_pheromone_map[route[i]][route[i+1]] = current_pheromone_value + new_pheromone_value
            self.ant_updated_pheromone_map[route[i+1]][route[i]] = current_pheromone_value + new_pheromone_value
        
    def mainloop(self):
        
        
        for _ in range(self.iterations):
            #start the multi-threaded ants,calls ant.run() in a new thread
            for ant in self.ants:
                ant.start()
            
            #source: http://stackoverflow.com/a/11968818/5343977
            #wait until the ants are finished,before moving on to modifying shared resources
            for ant in self.ants:
                ant.join()
            
            for ant in self.ants:   
                #update ant_updated_pheromone_map with this ant's constribution of pheromones along its route
                self._populate_ant_updated_pheromone_map(ant)
                
                #if we haven't seen any paths yet,then populate for comparisons later
                if not self.shortest_distance:
                    self.shortest_distance = ant.get_distance_traveled()
                
                if not self.shortest_path_seen:
                    self.shortest_path_seen = ant.get_route()
                    
                #if we see a shorter path,then save for return
                if ant.get_distance_traveled() < self.shortest_distance:
                    self.shortest_distance = ant.get_distance_traveled()
                    self.shortest_path_seen = ant.get_route()
            
            #decay current pheromone values and add all pheromone values we saw during traversal (from ant_updated_pheromone_map)
            self._update_pheromone_map()
            
            #flag that we finished the first pass of the ants traversal
            if self.first_pass:
                self.first_pass = False
            
            #reset all ants to default for the next iteration
            self._init_ants(self.start)
            
            #reset ant_updated_pheromone_map to record pheromones for ants on next pass
            self.ant_updated_pheromone_map = self._init_matrix(len(self.nodes),value=0)
        
        #translate shortest path back into callers node id's
        ret = []
        for id in self.shortest_path_seen:
            ret.append(self.id_to_key[id])
        
        return ret

我尝试了很多方法,但它们根本不起作用。我尝试测试两个坐标而不是 import ant_colony import math test_nodes = {0: (0,7),1: (3,9),2: (12,4),3: (14,11),4: (8,5: (15,6),6: (6,15),7: (15,8: (12,10),9: (10,7)} def distance(start,end): x_distance = abs(start[0] - end[0]) y_distance = abs(start[1] - end[1]) return math.sqrt(pow(x_distance,2) + pow(y_distance,2)) colony = ant_colony(test_nodes,distance) answer = colony.mainloop() print(answer) ,我尝试使用参数等进行测试,但它们不起作用。我该如何解决

解决方法

您正在导入模块而不是类。替换这行代码:

import ant_colony

用这行代码:

from ant_colony import ant_colony

有什么区别?在我的示例中,您从名为 ant_colony 的文件中导入名为 ant_colony 的类。第一个是文件路径,第二个是类名、函数名等

,

您可以看到错误提示 module 对象不可调用。因为当你写

import ant_colony

你所做的是导入整个模块,而你真正想要的只是类 所以你可以继续做

from ant_colony import ant_colony

你可以走了!

,

您必须将其称为 ant_colony.ant_colony(...) ,而不是 ant_colony(...) 请参阅此主题 TypeError: 'module' object is not callable