Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中分解dict和对象_Python - Fatal编程技术网

在Python中分解dict和对象

在Python中分解dict和对象,python,Python,在Javascript中,我可以使用一行代码从Javascript对象中提取所需的属性。例如: currentUser = { "id": 24, "name": "John Doe", "website": "http://mywebsite.com", "description": "I am an actor", "email": "example@example.com", "gender": "M", "phone_number": "+12345678",

在Javascript中,我可以使用一行代码从Javascript对象中提取所需的属性。例如:

currentUser = {
  "id": 24,
  "name": "John Doe",
  "website": "http://mywebsite.com",
  "description": "I am an actor",
  "email": "example@example.com",
  "gender": "M",
  "phone_number": "+12345678",
  "username": "johndoe",
  "birth_date": "1991-02-23",
  "followers": 46263,
  "following": 345,
  "like": 204,
  "comments": 9
}

let { id, username } = this.currentUser;
console.log(id) // 24
console.log(username) //johndoe
Python中是否有类似的Python dict和Python对象?Python处理Python对象的方式示例:

class User:
    def __init__(self, id, name, website, description, email, gender, phone_number, username):
        self.id = id
        self.name = name
        self.website = website
        self.description = description
        self.email = email
        self.gender = gender
        self.phone_number = phone_number
        self.username = username

current_user = User(24, "Jon Doe", "http://mywebsite.com", "I am an actor", "example@example.com", "M", "+12345678", "johndoe")

# This is a pain
id = current_user.id
email = current_user.email
gender = current_user.gender
username = current_user.username

print(id, email, gender, username)
像上面的例子中提到的那样写这4行,而不是像下面提到的那样写一行来从一个对象获取我需要的值,这是一个真正的痛点

(id, email, gender, username) = current_user
您可以实施_iter_______________________________

class User:
  def __init__(self, **data):
    self.__dict__ = data
  def __iter__(self):
    yield from [getattr(self, i) for i in ('id', 'email', 'gender', 'username')]

current_user = User(**currentUser)
id, email, gender, username = current_user
print([id, email, gender, username])
输出:

[24, 'example@example.com', 'M', 'johndoe']
编辑:Python2溶液:

class User:
  def __init__(self, **data):
    self.__dict__ = data
  def __iter__(self):
    for i in ('id', 'email', 'gender', 'username'):
      yield getattr(self, i)
编辑2:

获取选择属性:

class User:
  def __init__(self, **data):
     self.__dict__ = data
  def __getattr__(self, _vals):
     yield from [getattr(self, i) for i in _vals.split('_')]

current_user = User(**currentUser)
id, email, gender, username = current_user.id_email_gender_username
id, gender = current_user.id_gender

不要一开始就把论点抹平。当您像编写User那样编写8元函数时,您肯定会犯错误,例如以错误的顺序传递参数

以下哪项将产生您想要的用户

用户24,Jon Doe,http://mywebsite.com,我是一名演员,example@example.com,M,+12345678,约翰多 用户24,Jon Doe,http://mywebsite.com,我是一名演员,example@example.com+12345678米,约翰多 不可能知道!如果函数采用描述符,则不会出现此问题-

class User:
  def __init__ (self, desc = {}):
    self.desc = desc # whitelist items, if necessary
  
  def __str__ (self):
    # invent our own "destructuring" syntax
    [ name, age, gender ] = \
      destructure(self.desc, 'name', 'age', 'gender')

    return f"{name} ({gender}) is {age} years old"

# create users with a "descriptor"
u = User({ 'age': 2, 'gender': 'M' })
v = User({ 'gender': 'F', 'age': 3 })
x = User({ 'gender': 'F', 'name': 'Alice', 'age': 4 })

print(u) # None (M) is 2 years old
print(v) # None (F) is 3 years old
print(x) # Alice (F) is 4 years old
我们可以将自己的分解结构定义为-

这仍然可能导致长链,但顺序取决于调用方,因此它不像原始问题中的8元函数那样脆弱-

[ name, age, gender ] = \
  destructure(self.desc, 'name', 'age', 'gender')

# works the same as

[ gender, name, age ] = \
  destructure(self.desc, 'gender', 'name', 'age')
另一种选择是使用关键字参数-

class User:
  def __init__ (self, **desc):
    self.desc = desc # whitelist items, if necessary

  def __str__ (self):
    [ name, age, gender ] = \
      destructure(self.desc, 'name', 'age', 'gender')

    return f"{name} ({gender}) is {age} years old"

# create users with keyword arguments
u = User(age = 2, gender = 'M')
v = User(gender = 'F', age = 3)
x = User(gender = 'F', name = 'Alice', age = 4)

print(u) # None (M) is 2 years old
print(v) # None (F) is 3 years old
print(x) # Alice (F) is 4 years old
您可以使用标准库中的模块,如下所示:

from operator import attrgetter
id, email, gender, username = attrgetter('id', 'email', 'gender', 'username')(current_user)
print(id, email, gender, username)
以防你的例子中有类似的口述

currentUser = {
  "id": 24,
  "name": "John Doe",
  "website": "http://mywebsite.com",
  "description": "I am an actor",
  "email": "example@example.com",
  "gender": "M",
  "phone_number": "+12345678",
  "username": "johndoe",
  "birth_date": "1991-02-23",
  "followers": 46263,
  "following": 345,
  "like": 204,
  "comments": 9
}
只需使用itemgetter而不是attrgetter:


在其他答案的基础上,我建议也使用Python的数据类,并使用_ugetItem_uuuuuuuuuuuuuuuuuuuuuuuuuuuuuu来获取特定字段:

from dataclasses import astuple, dataclass

@dataclass
class User:
    id: int
    name: str
    website: str
    description: str
    email: str
    gender: str
    phone_number: str
    username: str
    
    def __iter__(self):
        return iter(astuple(self))
    
    def __getitem__(self, keys):
        return iter(getattr(self, k) for k in keys)
        

current_user = User(id=24, name="Jon Doe", website="http://mywebsite.com", description="I am an actor", email="example@example.com", gender="M", phone_number="+12345678", username="johndoe")

# Access fields sequentially:
id, _, email, *_ = current_user
# Access fields out of order:
id, email, gender, username = current_user["id", "email", "gender", "username"]

通过使用.values方法解包,可以销毁python字典并提取属性:


Python中的printcurrentUser['id']?可能与e.dan重复此问题的范围更广-包括dict和对象。关于第二个问题用户,请参阅ATTR库:。或者有这样一种方法:self.\u dict.\u.updatelocalsWhy您首先需要这些痛苦的句子?你不能直接从对象中访问值吗?如果我只想从对象中解包有限的字段,这将不起作用。例如:id,email=current\u用户此抛出值错误:值太多,无法unpack@LokeshAgrawal你可以使用一个一次性变量:id,email,*.=current\u userOh好的,谢谢你的建议,我认为语法的收益率是不正确的?@LokeshAgrawal不,是正确的,它正在创建一个可以迭代的生成器对象later@LokeshAgrawal是的,但是,我为python2添加了一个解决方案。谢谢你的回答。对于带有关键字args的函数,例如Username=Loki、gender=M、age=23,您有何看法?kwargs方式比用户{'name':'Loki','age':23,'gender':'M'}更受欢迎吗?谢谢,唯一的缺点是,因为我们将所有内容都存储在self.attr中,人们理解此类可能不直观,这也需要重写属性getter和setter。将具有可变集合的方法参数用作默认值是一个坏习惯。请改用“无”。如果声明def uu init uuu self,desc={}:并修改某个实例的user1.desc,比如user1=User;user1.desc['id']=1,则所有具有默认构造函数调用的新实例都将具有以下值:user2=User;printuser2.desc=>{'id':1}如果你有其他坏习惯,比如变异变量,这只是一个坏习惯:D我使用函数规则,所以我不会像其他人那样担心。只在Py3中提供是的,可能是时候升级到Python3了:从2020年1月1日起,不会对Python2进行新的错误报告、修复或更改,Python 2不再受支持。如果字典是动态创建的,并且调用代码不知道插入顺序或字典项,则此操作是否会中断?可能是中断。您是对的,如果字典结构和顺序是静态的,那么这是有效的
from operator import itemgetter
id, email, gender, username = itemgetter('id', 'email', 'gender', 'username')(currentUser)
print(id, email, gender, username)
from dataclasses import astuple, dataclass

@dataclass
class User:
    id: int
    name: str
    website: str
    description: str
    email: str
    gender: str
    phone_number: str
    username: str
    
    def __iter__(self):
        return iter(astuple(self))
    
    def __getitem__(self, keys):
        return iter(getattr(self, k) for k in keys)
        

current_user = User(id=24, name="Jon Doe", website="http://mywebsite.com", description="I am an actor", email="example@example.com", gender="M", phone_number="+12345678", username="johndoe")

# Access fields sequentially:
id, _, email, *_ = current_user
# Access fields out of order:
id, email, gender, username = current_user["id", "email", "gender", "username"]
 currentUser = {
  "id": 24,
  "name": "John Doe",
  "website": "http://mywebsite.com",
  "description": "I am an actor",
  "email": "example@example.com",
  "gender": "M",
  "phone_number": "+12345678",
  "username": "johndoe",
  "birth_date": "1991-02-23",
  "followers": 46263,
  "following": 345,
  "like": 204,
  "comments": 9
}

id, _, _, _, _, _, _, username, *other = currentUser.values()

print('distructuring:', { 'id': id, 'username': username })