<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def computers(self, base_dn, samaccountnames=(), attributes=()):
 """Gathers a list of ADComputer objects :param str base_dn: The base DN to search within :param list samaccountnames: A list of computer names for which objects will be created, defaults to all computers if unspecified :param list attributes: Object attributes to populate, defaults to all :return: A list of populated ADComputer objects :rtype: list """

        ad_computers = []

        search_filter = '(&(objectClass=computer){0})'
        # If no samaccountnames specified, filter will pull all computer objects under
        # base_dn
        if not samaccountnames:
            search_filter = search_filter.format('(sAMAccountName=*)')
        else:
            if len(samaccountnames) == 1:
                computer_names = '(sAMAccountName={0})'.format(samaccountnames[0])
            else:
                computer_names = '(|{0})'.format(''.join(['(sAMAccountName={0})'.\
                                                          format(computer) for computer
                                                          in samaccountnames]))

            search_filter = search_filter.format(computer_names)


        logging.debug('%s Search filter: %s', self.__class__.__name__, search_filter)

        results = self.adq.search(base_dn, search_filter, attributes)

        for search_result in results:
            adc = self._object_factory(search_result)
            ad_computers.append(adc)

        return ad_computers