如何从列表中动态生成 类?
How do you dynamically generate classes from a list?
我想创建一个 class 来自动添加我将来可以访问的值的持有者,这样当我 运行 cd.orders 或 cd.users 它将 return 或者给我一个我刚刚查询的每个表的数据框。
这是我的示例代码:
class samplecode:
def __init__(self,credentials):
c = credentials ('DATABASE', 'USER', 'PASSWORD', 'HOST', 'PORT', 'SCHEMA')
print('credentials loaded')
self.connection_string = "postgresql://%s:%s@%s:%s/%s" % (c.USER,
c.PASSWORD,
c.HOST,
str(c.PORT),
c.DATABASE)
self.engine = sa.create_engine(connection_string)
print('redshift connected')
self.data = []
def get_db(self,tables):
for t in tables:
self.data = pd.read_sql_query('SELECT * FROM database.{} limit 10'.format(t),engine)
print(self.data.head(2))
cd = samplecode(credential)
# llf.view_obj
cd.get_db(['orders','user'])
我希望在cd.get_db之后它会return或者给我两个instances/objects。当我输入 dir(cd)
我应该可以做 cd.orders 和 cd.user 如果我在列表中添加更多 cd.xyz.
我试过了,但只能访问最新的 df,因为它会覆盖其他 df
class Wrapper(object):
def __init__(self, data):
self.data = data
def __getattr__(self, attr):
return [d[attr] for d in self.data]
# Wrapper([{'x': 23}, {'x': 42}, {'x': 5}])
instancelist = ['orders','user']
for i in instancelist:
data = Wrapper([{i:'a'}])
cd.data
Hopnig 寻求帮助和澄清,谢谢!
或者如果这令人困惑,请考虑以下内容:
class BaseClass:
def __init__(self):
self.a = []
self.b = []
def execute_query(self,table_name):
for tables in table_name:
self.table_name = run_query()
table_list = ['D','E','F']
test = BaseClass
test.execute_query(table_list)
dir(test)
[
'a',
'b',
'D',
'E',
'F'
'__class__',
'__delattr__',
'__dict__',
'__dir__',
]
听起来您正在寻找 setattr
内置函数。您可以调用它来将属性(以字符串形式给出)分配给对象。因此,与其打印出您的 table,不如将每个分配给一个以 table 的名字命名的属性:
def get_db(self,tables):
for t in tables:
data = pd.read_sql_query('SELECT * FROM database.{} limit 10'.format(t), engine))
setattr(self, t, data)
您也可以反其道而行之,让属性查找触发数据库查询。为此,您需要向 class 添加一个 __getattr__
方法。当查找属性但正常找不到时将调用它。
def __getattr__(self, name):
data = pd.read_sql_query('SELECT * FROM database.{} limit 10'.format(name), engine))
setattr(self, name, data) # save to an attribute so we don't need to query it again
return data
我想创建一个 class 来自动添加我将来可以访问的值的持有者,这样当我 运行 cd.orders 或 cd.users 它将 return 或者给我一个我刚刚查询的每个表的数据框。
这是我的示例代码:
class samplecode:
def __init__(self,credentials):
c = credentials ('DATABASE', 'USER', 'PASSWORD', 'HOST', 'PORT', 'SCHEMA')
print('credentials loaded')
self.connection_string = "postgresql://%s:%s@%s:%s/%s" % (c.USER,
c.PASSWORD,
c.HOST,
str(c.PORT),
c.DATABASE)
self.engine = sa.create_engine(connection_string)
print('redshift connected')
self.data = []
def get_db(self,tables):
for t in tables:
self.data = pd.read_sql_query('SELECT * FROM database.{} limit 10'.format(t),engine)
print(self.data.head(2))
cd = samplecode(credential)
# llf.view_obj
cd.get_db(['orders','user'])
我希望在cd.get_db之后它会return或者给我两个instances/objects。当我输入 dir(cd)
我应该可以做 cd.orders 和 cd.user 如果我在列表中添加更多 cd.xyz.
我试过了,但只能访问最新的 df,因为它会覆盖其他 df
class Wrapper(object):
def __init__(self, data):
self.data = data
def __getattr__(self, attr):
return [d[attr] for d in self.data]
# Wrapper([{'x': 23}, {'x': 42}, {'x': 5}])
instancelist = ['orders','user']
for i in instancelist:
data = Wrapper([{i:'a'}])
cd.data
Hopnig 寻求帮助和澄清,谢谢!
或者如果这令人困惑,请考虑以下内容:
class BaseClass:
def __init__(self):
self.a = []
self.b = []
def execute_query(self,table_name):
for tables in table_name:
self.table_name = run_query()
table_list = ['D','E','F']
test = BaseClass
test.execute_query(table_list)
dir(test)
[
'a',
'b',
'D',
'E',
'F'
'__class__',
'__delattr__',
'__dict__',
'__dir__',
]
听起来您正在寻找 setattr
内置函数。您可以调用它来将属性(以字符串形式给出)分配给对象。因此,与其打印出您的 table,不如将每个分配给一个以 table 的名字命名的属性:
def get_db(self,tables):
for t in tables:
data = pd.read_sql_query('SELECT * FROM database.{} limit 10'.format(t), engine))
setattr(self, t, data)
您也可以反其道而行之,让属性查找触发数据库查询。为此,您需要向 class 添加一个 __getattr__
方法。当查找属性但正常找不到时将调用它。
def __getattr__(self, name):
data = pd.read_sql_query('SELECT * FROM database.{} limit 10'.format(name), engine))
setattr(self, name, data) # save to an attribute so we don't need to query it again
return data