Jupyter测试AnimalShelter类时出现'无create属性'报错求助
问题排查:'AnimalShelter'对象没有'create'属性
问题背景
在Jupyter Notebook测试自定义的AnimalShelter.py代码时,持续收到错误:'AnimalShelter'对象没有'create'属性,但已在类中定义create方法,附上完整代码及测试代码请求排查。
原代码展示
AnimalShelter.py
import pymongo from pymongo import MongoClient from bson.objectid import ObjectId class AnimalShelter(object): """ CRUD operations for Animal collection in MongoDB """ def __init__(self, username, password): #Initializing the MongoClient. This helps to access the MongoDB databases and collections. self.client = MongoClient('mongodb://%s:%s@localhost:45344' % (username, password)) #where xxxx is your unique port number self.database = self.client['AAC'] #Complete this create method to implement the C in CRUD. def create(self, data): if data is not None: insert = self.database.animals.insert(data) #data should be dictionary else: raise Exception("Nothing to save, because data parameter is empty") #Create method to implement the R in CRUD. def read(self, searchData): if searchData: data = self.database.animals.find(searchData, {"_id": False}) else: data = self.database.animals.find({}, {"_id": False}) return data #Create method to implement U in CRUD. def update(self, searchData, updateData): if searchData is not None: result = self.database.animals.update_many(searchData, {"$set": updateData}) else: return "{}" return result.raw_result #Create method to implement D in CRUD. def delete(self, deleteData): if deleteData is not None: result = self.database.animals.delete_many(deleteData) else: return "{}" return result.raw_result
测试代码
from AnimalShelter import AnimalShelter data = {} query = {} test_class = AnimalShelter() #test each function in the AnimalShelter class response = test_class.create(data) assert response response = test_class.read(data) assert response response = test_class.update(data) assert response response = test_class.delete(data) assert response
错误原因及修复步骤
1. 类方法缩进错误(核心问题)
原代码中create、read、update、delete方法未缩进,导致这些方法不属于AnimalShelter类的成员,而是全局函数。实例化对象后自然找不到create属性。
修复: 将所有方法缩进,使其与__init__方法对齐,成为类的内部方法。
2. __init__方法参数缺失
测试代码实例化AnimalShelter时未传入username和password,但类的构造方法明确要求这两个参数,会直接触发报错。
修复: 实例化时传入MongoDB的用户名和密码:
test_class = AnimalShelter('你的用户名', '你的密码')
3. create方法无返回值
原create方法执行插入操作后未返回结果,测试代码中的assert response会失败(因为response为None)。
修复: 在create方法中添加返回语句,同时替换过时的insert方法为insert_one:
def create(self, data): if data is not None and isinstance(data, dict): result = self.database.animals.insert_one(data) return result.inserted_id else: raise Exception("Nothing to save, because data parameter is empty or not a dictionary")
4. update方法参数不足
原update方法需要两个参数(searchData和updateData),但测试代码中只传了一个参数,会触发参数数量错误。
修复: 测试时传入更新数据:
response = test_class.update({"name": "测试狗狗"}, {"age": 3})
5. 空字典测试数据风险
测试用的data = {}会导致create方法抛出异常,同时delete(data)会删除集合中所有数据,建议使用非空测试数据:
test_data = {"name": "测试狗狗", "type": "狗", "age": 2}
修复后的完整代码
AnimalShelter.py
import pymongo from pymongo import MongoClient from bson.objectid import ObjectId class AnimalShelter(object): """ CRUD operations for Animal collection in MongoDB """ def __init__(self, username, password): #Initializing the MongoClient. This helps to access the MongoDB databases and collections. self.client = MongoClient('mongodb://%s:%s@localhost:45344' % (username, password)) #where xxxx is your unique port number self.database = self.client['AAC'] #Complete this create method to implement the C in CRUD. def create(self, data): if data is not None and isinstance(data, dict): result = self.database.animals.insert_one(data) return result.inserted_id else: raise Exception("Nothing to save, because data parameter is empty or not a dictionary") #Create method to implement the R in CRUD. def read(self, searchData): if searchData and isinstance(searchData, dict): data = self.database.animals.find(searchData, {"_id": False}) else: data = self.database.animals.find({}, {"_id": False}) return list(data) # 返回列表而非游标,方便断言 #Create method to implement U in CRUD. def update(self, searchData, updateData): if searchData is not None and isinstance(searchData, dict) and updateData: result = self.database.animals.update_many(searchData, {"$set": updateData}) return result.raw_result else: return "{}" #Create method to implement D in CRUD. def delete(self, deleteData): if deleteData is not None and isinstance(deleteData, dict): result = self.database.animals.delete_many(deleteData) return result.raw_result else: return "{}"
修复后的测试代码
from AnimalShelter import AnimalShelter # 使用非空测试数据 test_data = {"name": "测试狗狗", "type": "狗", "age": 2} update_data = {"age": 3} # 实例化时传入MongoDB的用户名和密码 test_class = AnimalShelter('你的用户名', '你的密码') # 测试create方法 response = test_class.create(test_data) assert response is not None # 测试read方法 response = test_class.read({"name": "测试狗狗"}) assert len(response) > 0 # 测试update方法 response = test_class.update({"name": "测试狗狗"}, update_data) assert response['nModified'] >= 0 # 测试delete方法 response = test_class.delete({"name": "测试狗狗"}) assert response['nRemoved'] >= 0
内容的提问来源于stack exchange,提问作者GuillyStudiesCode
相关产品推荐
相关产品推荐

