8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

修改Python中嵌套对象的最佳实践

CPlus 7月前

134 0
我正在使用Beanie ODM与MongoDB进行互动的Python项目,并且遇到了需要修改嵌套对象的情况。 具体来说,我正在处理一个用户对象,

我正在使用Beanie ODM与MongoDB进行交互的Python项目,并且遇到了需要修改嵌套对象的情况。

具体来说,我正在处理包含嵌套作业对象的用户对象(除其他属性)。 这是我正在使用的模型的简化版本:
from beanie import Document
from pydantic import BaseModel

class Job(BaseModel):
    title: str
    salary: int

class User(Document):
    name: str
    age: int
    job: Job

从数据库中检索 用户 实例后,我有几个功能可以修改 用户 及其嵌套 job 对象。

例如,更新用户的职位和薪水。 现在,这是我有点不确定的地方,以下示例:
from typing import Union
from beanie import init_beanie
from motor.motor_asyncio import AsyncIOMotorClient
import asyncio

async def fetch_user_by_name(name: str) -> Union[User, None]:
    user = await User.find_one(User.name == name)
    return user

def update_user_name(user: User, new_name: str) -> None:
    user.name = new_name

def update_user_job(user: User, new_title: str, new_salary: int) -> None:
    user.job.title = new_title
    user.job.salary = new_salary

async def main():
    # Initialize Beanie with database connection and document models
    client = AsyncIOMotorClient("mongodb://localhost:27017")
    await init_beanie(database=client.db_name, document_models=[User])

    # Example usage
    user = await fetch_user_by_name("Alice")
    if user:
        update_user_name(user, "Alice Updated")
        update_user_job(user, "Senior Developer", 90000)
        await user.save()
        print("User and job updated successfully.")
    else:
        print("User not found.")

这是一个非常基本的示例,真实的示例更为复杂,并使用更多的方法来基于依赖关系以及所有这些操作。

所以,这是我不确定的地方:我知道修改对象可能会导致意外行为,尤其是在较大的代码库或多线程环境中。

但是,由于Beanie返回我操纵的对象,因此我正在考虑处理此类修改的最佳方法。

问题:

  • 用Beanie ODM检索它们后,修改这些嵌套对象是否不良习惯?

我担心潜在的副作用或对代码可维护性的影响。
  • 在进行修改之前,最好创建对象的深度副本?

  • 这似乎可以避免意外的副作用,但是我担心性能的影响,尤其是在更复杂或更深的嵌套物体中。 我也可以将对象作为参数,对其进行修改并返回,但是已经对其进行了修改,因此返回该对象是没有意义的。

    什么将被认为是更好的练习,为什么?

    帖子版权声明 1、本帖标题: 修改Python中嵌套对象的最佳实践
        本站网址:http://xjnalaquan.com/
    2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
    3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
    4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
    5、站长邮箱:yeweds@126.com 除非注明,本帖由CPlus在本站《python》版块原创发布, 转载请注明出处!
    最新回复 (0)
    • pjs 7月前 0 只看Ta
      引用 2
      我认为脱钩有点困难,因为由于原因,它们被嵌套在数据库中。 将它们解耦也需要更多数据库查询,对吗? 我的要点是,将可变的物体传递出来,因为这可能会引起丑陋的副作用。 并拥有每个功能以从数据库中获取对象并将其写回来也感到很棒。 传递函数并返回结果时,创建每个对象的副本,也不会感觉不错。 我明白你在说的话,但我真的不觉得自己的榜样。
    • 我认为主要问题是我们正在处理包含更深层次结构的数据类别。 恐怕如果我们使它们保持可变,则代码库将很难管理。
    • 另一方面,这可能是OOP封装背后的整个想法,也许我应该只为Pydantic准备好/固定器。 也许我的头有点混乱。 对于那个很抱歉。
    • 正如目前所写的那样,您的答案尚不清楚。 请编辑以添加其他详细信息,以帮助其他人了解这如何解决问题。 您可以找到有关如何在帮助中心编写良好答案的更多信息。
    • 我有一个数据集,需要有条件地填充来自适当的groupby的第一个值,但我无法弄清楚。 导入numpy作为NP 导入大熊猫作为pd df_dict = { 'id':[1 ...

      我有一个数据集,我需要有条件地填充来自适当组的第一个值,但我无法弄清楚。

      import numpy as np
      import pandas as pd
      df_dict = {
          'id':[1, 1, 1, 1, 2, 2, 2, 2],
          'data':['A', np.nan, np.nan, np.nan, 'B', np.nan, np.nan, np.nan, 'C', np.nan, np.nan]
      }
      df = pd.DataFrame(df_dict)
      

      我需要创建一个看起来如下的数据框:

      final_dict = {
          'id':[1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2],
          'data':['A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'C', 'C', 'C']
      }
      final = pd.DataFrame(final_dict)
      

      我的Instince是groupby id ,然后做一个 .fillna(sothings) ,但我不知道该怎么办。

      我尝试了

      df.groupby('id')['data'].fillna(df['data'].first_valid_index())
      

      但这是 0 s而不是复制我想要的。

      我还有另一个部分解决方案:

      for col_name, data in df.items():
          df[col_name] = df.groupby('id').apply(
              lambda x: x[col_name].fillna(x.loc[x[col_name].last_valid_index(), col_name])
          ).reset_index(drop=True)
      
    • 谢谢! 这将与id = 2的最后3个一起使用,其中data ='c'?
    • 它将保留“ C”,但填充“ B”丢失。
    • Vika 7月前 0 只看Ta
      引用 9
      这假设在该组的第一个非零值之前没有填充的零值。 如果有的话,它会使他们无效。 那可能是您想要的,但您应该清楚差异。 同样,如果存在多个差距,则填补了最新的非零值,而不是组的第一个非磁性值。 同样,这可能是您想要的,但您应该知道区别。
    • 引用 10
      第一个假设是由我的数据设计的,第二个假设也是我想要的。
    • 那太好了。 另外,您的问题需要清理。 您的输入数据帧没有“ C”的提示。 您可能想提供有效的输入以实现所需的输出。 另外,您想向前填充并不明显,因此我的困惑。 您也可以通过更清晰地提高质量。 但是,在这样做时,您可能会使这个重复的问题……但这也可以。 如果您要我删除我的帖子,我会留给您。 它根本没有回答您的问题。
    • 引用 12
      我目前正在尝试编写一个将在目录中显示CSV的程序,然后您可以输入文件数,它将显示.CSV文件中写的内容。 我已经得到了所有内容...

      我目前正在尝试编写一个将在目录中显示CSV的程序,然后您可以输入文件数,它将显示在该文件中的内容。 CSV文件。

      我已经完成了所有工作,除非我投入一个数字,它显示了CSV中写的内容,然后显示了所有CSV。
      def seeProject():
          y = 1
          p = 0
          for x in os.listdir():
              if x.endswith(".csv"):
                  print(str(y)+". "+ x)
                  y = y+1
          f = input("Which would you like to open?\n")
          for x in os.listdir():
              if x.endswith (".csv") and p == int(f):
                  j = open(x,"r")
                  for w in j:
                      print(w)
              else:
                  p += 1
                  continue
      

      我尝试更改P值,但这无效。

      我确实尝试了按名称打开特定文件的实验,但有效,但是一些未来的文件的名称确实很长,我宁愿选择文件编号。 When I put in 1 I get:
      1. Herman.csv
      2. Jemma.csv
      Which would you like to open?
      1
      EROEIER,EEROIWEN,EOTIHNWET,0,WOIRH(*,WHR(*WR,WRUIWRH8,WRHWR*
      
      WRWRIUWBT,OIEGE,EPORTE(Tb,0,OEIRHWER(,WER(*WE,WBRUI8,IWBR8
      

      Putting in 2 gets me:

      1. Herman.csv
      2. Jemma.csv
      Which would you like to open?
      2
      WRWRIUWBT,OIEGE,EPORTE(Tb,0,OEIRHWER(,WER(*WE,WBRUI8,IWBR8
      ``
      
    • 引用 13
      您需要初始化
    • 不幸的是,当我将p设置为1时,它在输入1时不会显示任何内容,并且在输入2时显示了所有内容。
    • @johngordon我删除了该评论,因为我写了一个答案,说同样的话。
    • 为什么不是列表?
    • 对我来说,dict将列表上的文件编号更容易,以便更容易文件名映射。 files.get(输入('文件号码'),无)返回所选的文件名或无输入值不在文件中。
    • 引用 18
      我想通过从Excel文件中读取数据,执行测试然后在Python文件中输出结果来自动化测试过程。 到目前为止,我设法编写了几个类...

      我想通过从Excel文件中读取数据,执行测试然后在Python文件中输出结果来自动化测试过程。

      到目前为止,我设法编写了几个课程,这些课程在任务中执行并保存信息。

      在我的main()函数中,我创建实例,然后在这些实例中调用函数执行测试。

      现在,我想使用Python框架“ Textual”添加GUI。

      我无法将如何使用文字使用课堂实例来缠住我的头。 基本上,我想在按下按钮并随后输出结果时调用功能。

      这是我的后端代码。

      excelClass = excel_handling()
      excelClass.copyExcelFile("Test input data.xlsx")
      excelClass.readDataFromExcel()
      testDeviceClass = DeviceDataReader(excelClass.ipOfDevice)
      dataReaderClass = SerialReader(str(excelClass.comPort))
      dataReaderClass.initialize()
      #Should be called by a button
      runTests(excelClass, testDeviceClass, data)
      

      到目前为止,我的应用看起来像这样。

      将其连接到我的后端的最佳方法是什么?

      我没有添加 init ()函数并在GUI应用中创建后端类实例的外观。

      class ButtonArea(Static):       
          def on_button_pressed(self, event: Button.Pressed) -> None:
              """Event handler called when a button is pressed."""
              button_id = event.button.id
              if button_id == "start1":
                  pass
                  #run backend functions
              elif button_id == "start2":
                  pass
              elif button_id == "rereadExcel":
                  pass
          def compose(self)-> ComposeResult:
              yield Button("Start measurement 1", id="start1", variant = "success")
              yield Button("Start speed measurement", id="start2", variant = "success")
              yield Button("Reread Excel input file", id="rereadExcel", variant = "success")
      class GUI(App):
          CSS_PATH = "gui.tcss"
          def compose(self) -> ComposeResult:
              """Create child widgets for the app."""
              yield Header()
              yield Footer()
              with Horizontal(id= "ButtonArea"):
                  yield ButtonArea(guiInstance=self)
      
      def main():
          app = GUI()
          app.run()
       
      if __name__ == '__main__':
          main()
      
      

      谢谢您的帮助。

      请参阅上面的代码。

    • 引用 19
      源文件是JSON,我们将其划为GZ格式。 该文件很好。 我可以用记事本++打开文件 导入GZIP #在文本模式('rt')中打开GZIP文件 使用gzip.open('example.gz',...

      源文件是json,我们将其划为gz格式。

      该文件很好。 我可以用记事本++ 打开文件
      import gzip
      
      # Open the GZIP file in text mode ('rt')
      with gzip.open('example.gz', 'rt') as f:
          file_content = f.read()
          print(file_content)
      

      我得到的错误是

      badgzipfile:不是gzpipped文件(b'{\ n')

      我还尝试逐行读取并获得相同的错误

      import gzip
      
      with gzip.open('example.gz', 'r') as fin:
          for line in fin:
              print('got line:', line)
      
    返回
    作者最近主题: