Download

Defining object members in Python

Hello everyone!
I want to define a NON-UPROPERY member in Python, which is not successful with various methods. My code is as follows:


import unreal
import ftrack_api


@unreal.uclass()
class FTrackProxyImplementation(unreal.FTrackProxy):

    @unreal.ufunction(override=True)
    def create_session(self, url, key, username):
        try:
            self.__session = ftrack_api.Session(server_url = url, api_key = key, api_user = username)
            print(self.__session)
            return True
        except Exception:  
            return False

    @unreal.ufunction(override=True)
    def close_session(self):
        unreal.log_warning("This is the Python test")
        print(self.__session)

The following error occurred in the console:


LogPython: <ftrack_api.session.Session object at 0x000001FA1202BC50>
LogSlate: Window 'Message' being destroyed
LogPython: Warning: This is the Python test
LogScript: Error: Script Msg: Traceback (most recent call last):
  File "D:/MyProjects/RTXProject/Plugins/FTrackBridge/Content/Python/FTrackProxy.py", line 24, in close_session
    print(self.__session)
AttributeError: 'FTrackProxyImplementation' object has no attribute '_FTrackProxyImplementation__session'
LogScript: Error: Script call stack:
    FTrackProxyImplementation.CloseSession

Obviously, the members of the object (self.__session) have been destroyed. Is there a solution for it?
Thanks!

A Python object marked with uclass actually takes the Python definition, uses it to generate a UClass, and then re-writes the Python type to wrap that UClass.

As such it cannot reliably store data that isn’t in a UProperty, as only UProperties are added to the UClass and can be guaranteed to survive marshalling between the C++ instance and the Python wrapper.

If you do add data to the Python wrapper then it will survive only as long as the wrapper instance remains in scope.

Thank you for your reply!Finally, I solved this problem by referring to a native Python object.
So, anthor question. Is the function which is a Python object method can not be invoked in the a thread?


class FLoginTask : public FNonAbandonableTask
{
    friend class FAutoDeleteAsyncTask<FLoginTask>;

public:
    FLoginTask(const FOnLogin& InOnLogin)
        :OnLogin(InOnLogin)
    {}

    FORCEINLINE TStatId GetStatId() const
    {
        RETURN_QUICK_DECLARE_CYCLE_STAT(FLoginTask, STATGROUP_ThreadPoolAsyncTasks);
    }
    void DoWork()
    {    
        UE_LOG(LogTemp, Warning, TEXT("FLoginTask DoWork0"));
        const UAssetManagerSettings* AssetManagerSettings = GetDefault<UAssetManagerSettings>();
        UFTrackProxy* Proxy = UFTrackProxy::Get();
        if (AssetManagerSettings && Proxy)
        {
            FString URL = AssetManagerSettings->URL;
            UE_LOG(LogTemp, Warning, TEXT("FLoginTask DoWork1"));
            bool Result = Proxy->Login(AssetManagerSettings->URL,
                AssetManagerSettings->ApiKey,
                AssetManagerSettings->UserName);    
            UE_LOG(LogTemp, Warning, TEXT("FLoginTask DoWork2"));
            OnLogin.Execute(Result);
            UE_LOG(LogTemp, Warning, TEXT("FLoginTask DoWork3"));        
    }
private:
    FOnLogin OnLogin;
};

Function “Proxy->Login()” will eventually call a method of a python object,It will only print the following information to the console:


LogTemp: Warning: FLoginTask DoWork0
LogTemp: Warning: FLoginTask DoWork1

Because the Python API is a blocking mode, I want to call it in the thread.
Thanks!