社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

用python解构dict和objects

Lokesh Agrawal • 5 年前 • 2116 次点击  

在javascript中,我可以使用 destructuring 从一行的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
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/40848
 
2116 次点击  
文章 [ 2 ]  |  最新文章 5 年前
Ajax1234
Reply   •   1 楼
Ajax1234    6 年前

您可以实现 __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
user633183
Reply   •   2 楼
user633183    6 年前

不要一开始就把争论压扁。当你写一个8元函数的时候 User ,你一定会犯错误,比如按错误的顺序传递论点。

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

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

不可能知道!如果函数采用描述符,则不存在此问题-

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

我们可以定义自己的 destructure AS -

def destructure (d, *keys):
  return [ d[k] if k in d else None for k in keys ]

这仍然可能导致长链,但顺序取决于调用方,因此它不像原始问题中的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