Olá comunidade,
Neste artigo, vou descrever e ilustrar o processo de implementação do ObjectScript dentro do Python embutido. Esta discussão também fará referência a outros artigos relacionados ao Python embutido, bem como abordará questões que foram benéficas para a minha jornada de aprendizado.
Como você sabe, a integração de recursos Python dentro do IRIS tem sido possível há algum tempo. Este artigo se concentrará em como incorporar perfeitamente o ObjectScript com o Python embutido.
Essencialmente, o Python embutido serve como uma extensão que permite a escrita e execução independentes. Ele permite a integração perfeita do código Python com o ObjectScript e vice-versa, permitindo que ambos sejam executados dentro do mesmo contexto. Essa funcionalidade aprimora significativamente as capacidades da sua implementação.
Para começar, você deve especificar a linguagem para o seu código Python dentro da definição da classe usando a palavra-chave "language" [language = "python"]. Feito isso, você está preparado para escrever o seu código Python.
import iris -
O pacote iris é uma biblioteca Python vital que facilita a comunicação com as classes nativas, rotinas, globais e SQL do InterSystems. Este pacote está prontamente disponível por padrão. De qualquer forma, é necessário importar este pacote no início do seu código Python se você for interagir com o IRIS.
Algumas notas importantes antes de escrever
- Você pode usar a variável especial do Python
__name__
para se referir ao nome da classe dentro da definição da classe.
Use _ para %Methods ex: %New == _New , %OpenId == _OpenId
Vamos começar
Implementação de membros de classe em Python Embutid
1. Objetos e Propriedades
Esta seção é essencial, pois abordará o processo de inicialização de um novo objeto, alteração dos valores de objetos existentes e configuração de propriedades em contextos estáticos e dinâmicos. Crie sua própria definição de classe e use as propriedades literais simples
1.1 Inicializar novo Objeto / Modificar objeto existente
Use _New para iniciar um novo objeto e _OpenId(id) para editar o objeto existente
ClassMethod SaveIRISClsObject() [ Language = python ]
{
import iris
try:
iris_obj = iris.cls(__name__)._New()
if not iris.cls(__name__).IsObj(iris_obj):
raise ReferenceError('Object Initlize Error')
except ReferenceError as e:
print(e)
return
iris_obj.Name = 'Ashok'
iris_obj.Phone = 9639639635
status = iris_obj._Save()
print(status)
return status
}
1.2 Accessando propriedades
Antes de iniciar a seção sobre propriedades, é importante observar que o tipo de dados IRIS difere dos tipos de dados Python, e portanto, os tipos de dados de coleção IRIS não podem ser utilizados diretamente dentro do Python. Para solucionar isso, a InterSystems ofereceu uma solução abrangente para converter tipos de dados IRIS em formatos compatíveis com Python, como listas, conjuntos e tuplas. Isso pode ser alcançado importando o módulo "builtins" dentro da base de código IRIS, utilizando os métodos de classe ##class(%SYS.Python).Builtins() ou definindo builtins = ##class(%SYS.Python).Import("builtins").
Abordarei isso nas próximas seções.
Então, eu uso esse métood para converter as propriedades $LB em lista python para acessar as propriedades em tempo de execução no python.
LEARNING>Set pyList = ##class(%SYS.Python).ToList($LB("Name","Phone","City"))
LEARNING>zw pyList
pyList=5@%SYS.Python ; ['Name', 'Phone', 'City'] ; <OREF>
ClassMethod GetProperties() [Language = objectscript]
{
set pyList = ##class(%SYS.Python).ToList($LB("Name","Phone","City"))
do ..pyGetPropertiesAtRunTime(pyList)
}
ClassMethod pyGetPropertiesAtRunTime(properties) [ Language = python ]
{
import iris
iris_obj = iris.cls(__name__)._OpenId(1)
for prop in properties:
print(getattr(iris_obj,prop))
}
1.3 Defina propriedades em tempo de execução
Utilizo este dicionário Python para designar minha propriedade como chave e, com os valores de propriedade correspondentes servindo como valores dentro desse dicionário. Você pode consultar o código fornecido abaixo e a postagem da comunidade relacionada a essa configuração de propriedade.
ClassMethod SetProperties()
{
Set pyDict = ##class(%SYS.Python).Builtins().dict()
do pyDict.setdefault("Name1", "Ashok kumar")
do pyDict.setdefault("Phone", "9639639635")
do pyDict.setdefault("City", "Zanesville")
Set st = ..pySetPropertiesAtRunTime(pyDict)
}
ClassMethod pySetPropertiesAtRunTime(properties As %SYS.Python) [ Language = python ]
{
import iris
iris_obj = iris.cls(__name__)._New()
for prop in properties:
setattr(iris_obj, prop,properties[prop])
status = iris_obj._Save()
return status
}
1.4 Contexto de objetos compartilhados
Como mencionado anteriormente, tanto Python quanto ObjectScript operam dentro do mesmo contexto de memória e compartilham objetos. Isso significa que você pode criar ou abrir um objeto na classe InCache e posteriormente definir ou recuperá-lo na classe Python.
ClassMethod ClassObjectAccess() [Language = objectscript]
{
Set obj = ..%OpenId(1)
Write obj.PropAccess(),!
Do obj.DefineProperty("test")
Write obj.PropAccess()
}
Method PropAccess() [ Language = python ]
{
return self.Name
}
Method DefineProperty(name) [ Language = python ]
{
self.Name = name
}
2. Parâmetros
Obtenha o par chave-valor arbitrário do parâmetro usando o método _GetParameter. Consulte o útil post da comunidade.
ClassMethod GetParam(parameter = "MYPARAM") [ Language = python ]
{
import iris
value = iris.cls(__name__)._GetParameter(parameter)
print(value)
}
3. Class Method e Methods
3.1 Class Method
A invocação de métodos e funções de classe é altamente benéfica para a execução do código ObjectScript.
Invoque o método de classe como uma chamada estática, por exemplo: Do ..Test()
ClassMethod InvokeStaticClassMethods(clsName = "MyLearn.EmbeddedPython") [ Language = python ]
{
import iris
print(iris.cls(clsName).Test())
}
Invoque o método de classe em tempo de execução Set method="Test" Do $ClassMethod(class, method, args...)
ClassMethod InvokeClassMethodsRunTime(classMethod As %String = "Test") [ Language = python ]
{
import iris
clsMethodRef = getattr(iris.cls(__name__), classMethod)
print(clsMethodRef())
}
3.2 Methods
A invocação dos métodos de instância é feita da mesma forma que no formato 'ObjectScript'. No código abaixo, primeiro inicializo o objeto e, em seguida, chamo o método de instância com parâmetros.
ClassMethod InvokeInstanceMethodWithActualParameters() [ Language = python ]
{
import iris
obj = iris.cls(__name__)._New()
print(obj.TestMethod(1,2,4))
}
3.3 Passagem de argumentos por valor e por referência entre Python e ObjectScript
Basicamente, a passagem de argumentos é inevitável entre funções e seguirá o mesmo comportamento entre ObjectScript e Python.
3.4 Passagem por valor - É a passagem por valor usual.
ClassMethod passbyvalfromCOStoPY()
{
Set name = "test", dob= "12/2/2002", city="chennai"
Do ..pypassbyvalfromCOStoPY(name, dob, city)
}
ClassMethod pypassbyvalfromCOStoPY(name As %String, dob As %String, city As %String) [ Language = python ]
{
print(name,' ',dob,' ',city)
}
ClassMethod pypassbyvalfromPY2COS() [ Language = python ]
{
import iris
name = 'test'
dob='12/2/2002'
city='chennai'
iris.cls(__name__).passbyvalfromPY2COS(name, dob, city)
}
ClassMethod passbyvalfromPY2COS(name As %String, dob As %String, city As %String)
{
zwrite name,dob,city
}
3.5 Passagem por referência - Diferentemente da passagem por valor. Como o Python não suporta nativamente a passagem por referência, é necessário utilizar o iris.ref() no código Python para tornar a variável uma referência. Consulte a referência. Pelo que sei, não há efeitos no lado ObjectScript em relação a variáveis passadas por referência, mesmo quando essas variáveis são modificadas em Python. Consequentemente, as variáveis Python serão afetadas por esse mecanismo de passagem por referência quando os métodos do ObjectScript forem invocados.
ClassMethod pypassbyReffromPY2COS() [ Language = python ]
{
import iris
name='python'
dob=iris.ref('01/01/1991')
city = iris.ref('chennai')
print('before COS ',name,' ',dob.value,' ',city.value)
#pass by reference of dob, city
iris.cls('MyLearn.EmbeddedPythonUtils').passbyReffromPY2COS(name, dob, city)
print('after COS ',name,' ',dob.value,' ',city.value)
}
ClassMethod passbyReffromPY2COS(name, ByRef dob, ByRef city)
{
Set name="object script", dob="12/12/2012", city="miami"
}
LEARNING>do ##class(MyLearn.EmbeddedPythonUtils).pypassbyReffromPY2COS()
before COS python 01/01/1991 chennai
after COS python 12/12/2012 miami
3.5 **kwargs- Existe suporte adicional para passar argumentos de palavra-chave Python (**kwargs)a partir do ObjectScript. Como o InterSystems IRIS não possui o conceito de argumentos de palavra-chave, é necessário criar um %DynamicObject para armazenar os pares chave-valor e passar os valores usando a sintaxe Args...
Eu criei o dynamicObject { "name": "ashok", "city": "chennai"}
e nele defini os pares chave-valor necessários, passando-o posteriormente ao código Python.
ClassMethod KWArgs()
{
set kwargs={ "name": "ashok", "city": "chennai"}
do ..pyKWArgs(kwargs...)
}
ClassMethod pyKWArgs(name, city, dob = "") [ Language = python ]
{
print(name, city, dob)
}
LEARNING>do ##class(MyLearn.EmbeddedPythonUtils).KWArgs()
ashok chennai
No próximo artigo, tratarei de assuntos como variáveis globais, rotinas e SQL.