向类添加属性的更多 Pythonic 方式? [英] More Pythonic way of adding attributes to class?

查看:43
本文介绍了向类添加属性的更多 Pythonic 方式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在处理来自两个不同网页的数据集,但对于同一个人 - 数据集是合法信息.有些数据在第一页上是可用的,所以我用正确的信息初始化了一个 Defendant 对象,并将我目前没有数据的属性设置为 null.这是课程:

I'm working with datasets from two different webpages, but for the same individual - the data sets are legal info on. Some of the data is available on the first page, so I initialize a Defendant object with the proper info, and set the attributes that I don't currently have the data for to null. This is the class:

class Defendant(object):
    """holds data for each individual defendant"""
    def __init__(self,full_name,first_name,last_name,type_of_appeal,county,case_number,date_of_filing,
                 race,sex,dc_number,hair_color,eye_color,height,weight,birth_date,initial_receipt_date,current_facility,current_custody,current_release_date,link_to_page):
        self.full_name = full_name
        self.first_name = first_name
        self.last_name = last_name
        self.type_of_appeal = type_of_appeal
        self.county = county
        self.case_number = case_number
        self.date_of_filing = date_of_filing
        self.race = 'null'
        self.sex = 'null'
        self.dc_number = 'null'
        self.hair_color = 'null'
        self.eye_color = 'null'
        self.height = 'null'
        self.weight = 'null'
        self.birth_date = 'null'
        self.initial_receipt_date = 'null'
        self.current_facility = 'null'
        self.current_custody = 'null'
        self.current_release_date = 'null'
        self.link_to_page = link_to_page

当我将一个填写一半的 Defendant 对象添加到被告列表中时,它看起来是这样的:

And this is what it looks like when I add a half-filled out Defendant object to a list of defendants:

list_of_defendants.append(Defendant(name_final,'null','null',type_of_appeal_final,county_parsed_final,case_number,date_of_filing,'null','null','null','null','null','null','null','null','null','null','null','null',link_to_page))

然后,当我从另一个页面获取其余数据时,我将这些属性设置为 null,如下所示:

then, when I get the rest of the data from the other page I update those attributes set to null like so:

        for defendant in list_of_defendants:
            defendant.sex = location_of_sex_on_page
            defendant.first_name = location_of_first_name_on_page
            ## Etc.

我的问题是:当我只有一半的信息要存储在类对象中时,是否有更 Pythonic 的方式向类添加属性或不那么丑陋的初始化类对象的方式?

My question is: is there a more pythonic way to either add attributes to a class or a less ugly way of initializing the class object when I only have half of the information that I want to store in it?

推荐答案

首先,对您设置为 null 的任何参数使用默认值.这样,您甚至不需要在实例化对象时指定这些参数(并且您可以使用参数名称以任何顺序指定您需要的任何参数).对于这些,您应该使用 Python 值 None 而不是字符串 "null" ,除非有使用字符串的某些特定原因.在 Python 2.x 中,具有默认值的参数需要放在最后,因此 link_to_page 需要移动到这些之前.

First, use default values for any arguments that you're setting to null. This way you don't even need to specify these arguments when instantiating the object (and you can specify any you do need in any order by using the argument name). You should use the Python value None rather than the string "null" for these, unless there is some specific reason for using the string. In Python 2.x, arguments with default values need to go last, so link_to_page needs to be moved before these.

然后,您可以通过更新实例的 __dict__ 属性来设置您的属性,该属性存储附加到实例的属性.每个参数将被设置为具有相同名称的实例的一个属性.

Then, you can set your attributes by updating the instance's __dict__ attribute, which stores the attributes attached to the instance. Each argument will be set as an attribute of the instance having the same name.

def __init__(self, full_name, first_name, last_name, type_of_appeal, county, case_number, 
             date_of_filing, link_to_page, race=None, sex=None, dc_number=None,
             hair_color=None, eye_color=None, height=None, weight=None, birth_date=None,
             initial_receipt_date=None, current_facility=None, current_custody=None, 
             current_release_date=None):

      # set all arguments as attributes of this instance
      code     = self.__init__.__func__.func_code
      argnames = code.co_varnames[1:code.co_argcount]
      locs     = locals()
      self.__dict__.update((name, locs[name]) for name in argnames)

您还可以考虑从其他两个名称参数中合成 full_name.那么你就不必传入冗余信息,它永远不会不匹配.您可以通过属性即时执行此操作:

You might also consider synthesizing the full_name from the two other name arguments. Then you don't have to pass in redundant information and it can never not match. You can do this on the fly via a property:

@property
def full_name(self):
    return self.first_name + " " + self.last_name

为了更新,我会添加一个方法来做到这一点,但使用 ** 接受仅关键字参数.为帮助保护数据的完整性,我们将仅更改已存在且设置为 None 的属性.

For updating, I'd add a method to do that, but accept keyword-only arguments using **. To help protect the integrity of the data, we will change only attributes that already exist and are set to None.

def update(self, **kwargs):
    self.__dict__.update((k, kwargs[k]) for k in kwargs
                          if self.__dict__.get(k, False) is None)

然后,您只需一次调用即可轻松更新所需的所有内容:

Then you can easily update all the ones you want with a single call:

defendant.update(eye_color="Brown", hair_color="Black", sex="Male")

要确保实例已完全填充,您可以添加一个方法或属性来检查以确保所有属性都不是None:

To make sure an instance has been completely filled out, you can add a method or property that checks to make sure all attributes are not None:

@property
def valid(self):
    return all(self.__dict__[k] is not None for k in self.__dict__)

这篇关于向类添加属性的更多 Pythonic 方式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆