Существует простой трюк Java для решения вашей проблемы. Вы должны указать экземпляр Class.forName()
. Например:
val customers: RDD[(Int, String)] = new JdbcRDD(sc, () => {
Class.forName("com.mysql.jdbc.Driver")
DriverManager.getConnection(jdbcUrl)
},
"SELECT id, name from customer WHERE ? < id and id <= ?" ,
0, range, partitions, r => (r.getInt(1), r.getString(2)))
Проверьте документы
У экземпляров нет имен. К тому моменту, когда глобальное имя ThisObject
привязано к экземпляру, созданному при оценке конструктора SomeObject
, конструктор закончил работу.
Если вы хотите, чтобы объект имел имя, просто передайте имя в конструкторе.
def __init__(self, name):
self.name = name
Я думаю, что имена имеют значение, если они являются указателями на какой-либо объект .. не имеет значения, если:
foo = 1
bar = foo
Я знаю, что foo указывает на 1 и штрих указывает на одно и то же значение 1 в одно и то же памяти. но предположим, что я хочу создать класс с функцией, которая добавляет к нему объект.
Class Bag(object):
def __init__(self):
some code here...
def addItem(self,item):
self.__dict__[somewaytogetItemName] = item
Итак, когда я создаю пакет класса, как показано ниже:
newObj1 = Bag()
newObj2 = Bag()
newObj1.addItem(newObj2)I can do this to get an attribute of newObj1:
newObj1.newObj2
В Python все данные хранятся в объектах. Кроме того, имя может быть связано с объектом, после чего это имя может быть использовано для поиска этого объекта.
Не имеет никакого значения для объекта, какие имена, если таковые имеются, могут быть связаны. Это может быть связано с десятками разных имен или нет. Кроме того, у Python нет никаких «обратных ссылок», которые указывают от объекта к имени.
Рассмотрим этот пример:
foo = 1
bar = foo
baz = foo
Теперь предположим, что у вас есть целочисленный объект с значение 1, и вы хотите работать назад и найти свое имя. Что бы вы напечатали?
print(bar is foo) # prints True
print(baz is foo) # prints True
В Python имя является способом доступа к объекту, поэтому нет возможности напрямую работать с именами. Вы можете искать через различные пространства имен, пока не найдете имя, связанное с объектом интереса, но я не рекомендую это.
Как получить строковое представление переменной в python?
Существует известная презентация под названием «Code Like a Pythonista», которая суммирует эту ситуацию как «Другие языки имеют« переменные »и« у Python есть имена »
http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html# другие языки-чтобы-переменные
a = b
; на C-подобном языке это означает, что значение i> скопировано i>, но в Python это означает, что name i> is re-bound < / я>. Это различие, которое я пытался объяснить. Прошу прощения, что вы нашли мое объяснение трудным для понимания.
– steveha
20 June 2013 в 21:13
Лучший способ - это передать имя конструктору, как в выбранном ответе. Однако, если вы действительно НЕ хотите, чтобы пользователь не передавал имя конструктору, вы можете выполнить следующий взлом:
Если вы создаете экземпляр с помощью «ThisObject = SomeObject ()» из команды line, вы можете получить имя объекта из командной строки в истории команд:
import readline
import re
class SomeObject():
def __init__(self):
cmd = readline.get_history_item(readline.get_current_history_length())
self.name = re.split('=| ',cmd)[0]
Если вы создаете экземпляр с помощью команды «exec», вы можете справиться с этим с помощью:
if cmd[0:4] == 'exec': self.name = re.split('\'|=| ',cmd)[1] # if command performed using 'exec'
else: self.name = re.split('=| ',cmd)[0]
Если вы хотите уникальное имя экземпляра для класса, попробуйте __repr__()
или id(self)
class Some:
def __init__(self):
print(self.__repr__()) # = hex(id(self))
print(id(self))
Он распечатает адрес памяти экземпляра, который является уникальным.
Это не сработает, просто представьте это: a = b = TheMagicObjet()
. Имена не влияют на значения, они просто указывают на них.
L = [TheMagicObjet() for x in xrange(10)]
?
– u0b34a0f6ae
7 November 2009 в 01:58
Один ужасный, ужасный способ добиться этого - отменить обязанности:
class SomeObject():
def __init__(self, def_name):
self.defined_name = def_name
globals()[def_name] = self
SomeObject("ThisObject")
print ThisObject.defined_name
Если вы хотите поддержать что-то иное, чем глобальное пространство, вам придется сделать что-то еще более ужасное.
Вы можете создать метод внутри вашего класса, который проверяет все переменные в текущем фрейме и использует hash()
для поиска переменной self
.
Предлагаемое здесь решение вернет все переменные, указывающие к объекту экземпляра.
В приведенном ниже классе isinstance()
используется, чтобы избежать проблем при применении hash()
, так как некоторые объекты, такие как numpy.array
или list
, например, не сбрасываются .
import inspect
class A(object):
def get_my_name(self):
ans = []
frame = inspect.currentframe().f_back
tmp = dict(frame.f_globals.items() + frame.f_locals.items())
for k, var in tmp.items():
if isinstance(var, self.__class__):
if hash(self) == hash(var):
ans.append(k)
return ans
Выполнен следующий тест:
def test():
a = A()
b = a
c = b
print c.get_my_name()
Результат:
test()
#['a', 'c', 'b']
Вдохновленный ответами unutbu и Saullo Castro, я создал более сложный класс, который может быть даже подклассифицирован. Он решает, что было задано в вопросе.
"создать значение по умолчанию, основанное на имени экземпляра класса, не передавая дополнительный аргумент."
blockquote>Вот что он делает, когда экземпляр этого класса или подкласса:
- Перейти в стек кадров до первого кадра, который не принадлежит методу текущего экземпляра.
- Осмотреть это кадр для получения атрибутов
self.creation_(name/file/module/function/line/text)
.- Выполните дополнительную проверку, действительно ли объект с именем
self.creation_name
был определен в пространстве имен locals () фрейма, чтобы сделать 100% уверенным, что найденное имя_создания является правильным или /// g2]Код:
import traceback, threading, time class InstanceCreationError(Exception): pass class RememberInstanceCreationInfo: def __init__(self): for frame, line in traceback.walk_stack(None): varnames = frame.f_code.co_varnames if varnames is (): break if frame.f_locals[varnames[0]] not in (self, self.__class__): break # if the frame is inside a method of this instance, # the first argument usually contains either the instance or # its class # we want to find the first frame, where this is not the case else: raise InstanceCreationError("No suitable outer frame found.") self._outer_frame = frame self.creation_module = frame.f_globals["__name__"] self.creation_file, self.creation_line, self.creation_function, \ self.creation_text = \ traceback.extract_stack(frame, 1)[0] self.creation_name = self.creation_text.split("=")[0].strip() super().__init__() threading.Thread(target=self._check_existence_after_creation).start() def _check_existence_after_creation(self): while self._outer_frame.f_lineno == self.creation_line: time.sleep(0.01) # this is executed as soon as the line number changes # now we can be sure the instance was actually created error = InstanceCreationError( "\nCreation name not found in creation frame.\ncreation_file: " "%s \ncreation_line: %s \ncreation_text: %s\ncreation_name (" "might be wrong): %s" % ( self.creation_file, self.creation_line, self.creation_text, self.creation_name)) nameparts = self.creation_name.split(".") try: var = self._outer_frame.f_locals[nameparts[0]] except KeyError: raise error finally: del self._outer_frame # make sure we have no permament inter frame reference # which could hinder garbage collection try: for name in nameparts[1:]: var = getattr(var, name) except AttributeError: raise error if var is not self: raise error def __repr__(self): return super().__repr__()[ :-1] + " with creation_name '%s'>" % self.creation_name
Простой пример:
class MySubclass(RememberInstanceCreationInfo): def __init__(self): super().__init__() def print_creation_info(self): print(self.creation_name, self.creation_module, self.creation_function, self.creation_line, self.creation_text, sep=", ") instance = MySubclass() #out: instance, __main__, <module>, 68, instance = MySubclass()
Если имя создания не может быть определено правильно возникает ошибка:
variable, another_instance = 2, MySubclass() # InstanceCreationError: # Creation name not found in creation frame. # creation_file: /.../myfile.py # creation_line: 71 # creation_text: variable, another_instance = 2, MySubclass() # creation_name (might be wrong): variable, another_instance
Ну, есть почти способ сделать это:
#!/usr/bin/env python
import traceback
class SomeObject():
def __init__(self, def_name=None):
if def_name == None:
(filename,line_number,function_name,text)=traceback.extract_stack()[-2]
def_name = text[:text.find('=')].strip()
self.defined_name = def_name
ThisObject = SomeObject()
print ThisObject.defined_name
# ThisObject
Модуль трассировки позволяет вам заглянуть в код, используемый для вызова SomeObject (). С небольшими переборками строк text[:text.find('=')].strip()
вы можете догадаться, что должно быть def_name.
Однако этот хак хрупкий. Например, это не работает так хорошо:
ThisObject,ThatObject = SomeObject(),SomeObject()
print ThisObject.defined_name
# ThisObject,ThatObject
print ThatObject.defined_name
# ThisObject,ThatObject
Итак, если бы вы использовали этот хак, вы должны иметь в виду, что вы должны вызвать SomeObject (), используя простой оператор python:
ThisObject = SomeObject()
Кстати, в качестве еще одного примера использования traceback, если вы определяете
def pv(var):
# stack is a list of 4-tuples: (filename, line number, function name, text)
# see http://docs.python.org/library/traceback.html#module-traceback
#
(filename,line_number,function_name,text)=traceback.extract_stack()[-2]
# ('x_traceback.py', 18, 'f', 'print_var(y)')
print('%s: %s'%(text[text.find('(')+1:-1],var))
, вы можете вызвать
x=3.14
pv(x)
# x: 3.14
, чтобы напечатать оба имя переменной и ее значение.