这就是我想要做的事情:
obj = object()
obj.(a,b,c) = 1,2,3
f(obj.(d,e))
这就是我所知道的:
obj = object()
obj.a, obj.b, obj.c = 1,2,3
在Python中有没有这样做的语法?
后续问题:
(“你为什么要这样做?”因为我有时候会直觉地将成员变量组视为一个包。有些类是有意义的,比如固定维度点,或者复数。)
答案 0 :(得分:3)
我认为没有确切的语法,但对我来说这感觉类似:
class Thing:
def __init__(self, x, y):
self.point = (x, y)
def __getattr__(self, name):
if name == "x":
return self.point[0]
elif name == "y":
return self.point[1]
else:
raise AttributeError
def __setattr__(self, name, value):
if name == "x":
self.point = (value, self.point[1])
elif name == "y":
self.point = (self.point[0], value)
else:
object.__setattr__(self, name, value)
thing = Thing(4, 7)
thing.point = (3, 6)
thing.x = 5
答案 1 :(得分:1)
由于grammar of attribute references而无法实现。
属性引用是主要的,后跟句点和名称:
attributeref ::= primary "." identifier
identifier必须以字母开头,而不是括号。
标识符(也称为名称)由以下描述 词汇定义:
identifier ::= (letter|"_") (letter | digit | "_")*
letter ::= lowercase | uppercase
lowercase ::= "a"..."z"
uppercase ::= "A"..."Z"
digit ::= "0"..."9"
这意味着,无论您对SyntaxError
和/或__getattr__
进行多少黑客攻击,都会获得__getattribute__
。
答案 2 :(得分:0)
没有“成员元组”语法正是您所描述的那种。但是,这是一个可能的解决方法,用于设置属性的“元组”并传递属性的“元组”。它有点笨重,所以我不知道我是否真的想要使用它。
class MyClass:
pass
def set_tuple(obj, **attrs):
for key in attrs:
setattr(obj, key, attrs[key])
def pass_tuple(obj, *attrnames):
return (getattr(obj, x) for x in attrnames)
def print_things(*iterable):
for x in iterable:
print(x)
obj = MyClass()
set_tuple(obj, a=1, b=2, c=3)
print(obj.a, obj.b, obj.c, '\n')
print_things(*pass_tuple(obj, 'a', 'c'))
结果:
1 2 3
1
3
答案 3 :(得分:0)
根据sweeneyrod的答案,我写了一种方法,有一些类似的语法,用逗号分隔的字符串和方括号。用法:
thing = myclass()
thing['x,y'] = 3,6
x,y = thing['x,y']
thing['x,y,z'] = 1,2,3
这给出了
>>> x
3
>>> y
6
>>> thing.x
1
>>> thing.z
3
班级定义:
#user class
class myclass:
def __getitem__(self,keys):
keys = keys.split(',')
return tuple(getattr(self, attr) for attr in keys)
def __setitem__(self,keys,values):
keys = keys.split(',')
if len(keys) != len(values):
raise ValueError('too many values to unpack (expected %d)'%len(keys))
for attr,val in zip(keys, values):
setattr(self, attr, val)
def __delitem__(self,keys):
keys = keys.split(',')
for attr in keys:
delattr(self, attr)
的问题:
__getitem__
重叠。__setattr__
抛出异常吗?)我原本以为使用thing.grouping('x,y')=3,6
,但我忘记了我无法分配给函数调用。
装饰者版:
try:
from itertools import izip as zip #python 2
except:
pass #python 3 already has zip
#decorator
def attribute_tuple(cls):
if not hasattr(attribute_tuple,'initialized'):
attribute_tuple.initialized=True
def get(self,keys):
keys = keys.split(',')
return tuple(getattr(self, attr) for attr in keys)
attribute_tuple.get = get
def set(self,keys,values):
keys = keys.split(',')
if len(keys) != len(values):
raise ValueError('too many values to unpack (expected %d)'%len(keys))
for attr,val in zip(keys, values):
setattr(self, attr, val)
attribute_tuple.set = set
def delete(self,keys):
keys = keys.split(',')
for attr in keys:
delattr(self, attr)
attribute_tuple.delete = delete
cls.__getitem__ = attribute_tuple.get
cls.__setitem__ = attribute_tuple.set
cls.__delitem__ = attribute_tuple.delete
return cls
@attribute_tuple
class myclass:
pass